home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / muds / pennmush.000 / pennmush-1.50-p8-linux.tar / pennmush / game.c < prev    next >
C/C++ Source or Header  |  1993-10-22  |  76KB  |  3,200 lines

  1. /* game.c */
  2.  
  3. #include <ctype.h>
  4. #include <fcntl.h>
  5. #include <string.h>
  6. #ifdef XENIX
  7. #include <sys/signal.h>
  8. #else
  9. #include <signal.h>
  10. #include <sys/wait.h>
  11. #endif                /* xenix */
  12.  
  13. #include <sys/time.h>
  14. #include <sys/types.h>
  15.  
  16. #include "config.h"
  17. #include "db.h"
  18. #include "game.h"
  19. #include "externs.h"
  20. #include "interface.h"
  21. #include "match.h"
  22. #include "globals.h"
  23.  
  24. #ifdef HAS_RUSAGE
  25. #include <sys/resource.h>
  26. #endif
  27.  
  28. #ifdef MEM_CHECK
  29. #include "mem_check.h"
  30. #endif
  31.  
  32.  
  33. /* declarations */
  34. char dumpfile[200];
  35. static time_t start_time;    /* MUSH start time */
  36. static int epoch = 0;
  37. int reserved;
  38. int depth = 0;            /* excessive recursion prevention */
  39. extern int invok_counter;    /* function recursion prevention */
  40. extern dbref cplr;
  41. extern char ccom[];
  42. extern char rptr[10][BUFFER_LEN]; /* from eval.c */
  43.  
  44. static int paranoid_dump = 0;   /* if paranoid, scan before dumping */
  45. int paranoid_checkpt = 0;       /* write out an okay message every x objs */
  46. void fork_and_dump();
  47. void dump_database();
  48.  
  49. #ifdef DBSTATS_ENABLED
  50. extern void do_dbstats();
  51. #endif
  52.  
  53. extern dbref first_free;    /* head of free object list, destroy.c */
  54.  
  55. dbref speaker = NOTHING;
  56.  
  57. /*
  58.  * used to allocate storage for temporary stuff, cleared before command
  59.  * execution
  60.  */
  61.  
  62. void do_dump(player, num, flag)
  63.      dbref player;
  64.      char *num;
  65.      int flag;            
  66. {
  67.     /* if flag is 0, do a normal dump. otherwise, do a paranoid dump */
  68.     
  69.     time_t tt;
  70.     if (Wizard(player)) {
  71.     if (options.daytime) {
  72.         notify(player, "Sorry, CPU intensive commands are currently disabled.");
  73.         return;
  74.     }
  75.     tt = time((time_t *) 0);
  76.     if (flag) {
  77.         /* want to do a scan before dumping each object */
  78.         paranoid_dump = 1;
  79.         if (num && *num) {
  80.         /* checkpoint interval given */
  81.         paranoid_checkpt = atoi(num);
  82.         if ((paranoid_checkpt < 1) || (paranoid_checkpt >= db_top)) {
  83.             notify(player, "Permission denied. Invalid checkpoint interval.");
  84.             paranoid_dump = 0;
  85.             return;
  86.         }
  87.         } else {
  88.         /* use a default interval */
  89.         paranoid_checkpt = db_top / 5;
  90.         if (paranoid_checkpt < 1)
  91.             paranoid_checkpt = 1;
  92.         }
  93.         notify(player, tprintf("Paranoid dumping, checkpoint interval %d.",
  94.                    paranoid_checkpt));
  95.         fprintf(checklog_fp, 
  96.             "*** PARANOID DUMP *** done by %s(#%d),\n",
  97.             db[player].name, player);
  98.         fprintf(checklog_fp, "\tcheckpoint interval %d, at %s",
  99.             paranoid_checkpt, ctime(&tt));
  100.     } else {
  101.         /* normal dump */
  102.         paranoid_dump = 0;    /* just to be safe */
  103.         notify(player, "Dumping...");
  104.         fprintf(checklog_fp, "** DUMP ** done by %s(#%d) at %s",
  105.             db[player].name, player, ctime(&tt));
  106.     }
  107.     fflush(checklog_fp);
  108.     fork_and_dump();
  109.     paranoid_dump = 0;
  110.     } else {
  111.     notify(player, "Sorry, you are in a no dumping zone.");
  112.     }
  113. }
  114.  
  115.  
  116. /* print out stuff into error file */
  117. void report()
  118. {
  119. #ifdef REPORT_TRACES
  120.     fprintf(tracelog_fp, "****REPORT TRACE!****\n\tCommand:%s\tdepth:%d\n", ccom,
  121.         depth);
  122.     fflush(tracelog_fp);
  123.     if ((cplr > 0) && (cplr <= db_top))
  124.     fprintf(tracelog_fp, "\tPlayer #%d\n\tlocation #%d\n", cplr, 
  125.         db[cplr].location);
  126. #else
  127.     fprintf(tracelog_fp, "TRACE: Cmd %s, depth %d", ccom, depth);
  128.     if (GoodObject(cplr))
  129.     fprintf(tracelog_fp, ", from #%d at #%d\n", cplr, Location(cplr));
  130.     else
  131.     fprintf(tracelog_fp, "\n");
  132. #endif                /* REPORT_TRACES */
  133.     fflush(tracelog_fp);
  134. }
  135.  
  136. #ifdef DESTROY
  137. void do_purge(player)
  138.      dbref player;
  139. {
  140.     if (Wizard(player)) {
  141.     FIX;
  142.     notify(player, "Purge complete.");
  143.     } else
  144.     notify(player, "Sorry, you are a mortal.");
  145. }
  146.  
  147. void dest_info(thing, tt)
  148.      dbref thing;
  149.      dbref tt;
  150. {
  151.     if (thing == NOTHING && !Floating(tt)) {
  152.     if (db[tt].name) {
  153.         notify(db[tt].owner, tprintf("You own a disconnected room, %s(#%d)",
  154.                      db[tt].name, tt));
  155.     } else
  156.         do_log(LT_ERR, NOTHING, NOTHING, "ERROR: no name for room #%d.", tt);
  157.     return;
  158.     }
  159.     
  160.     /* hopefully this check will remove some odd messages when things for
  161.      * some reason get marked wrong? Just a guess. Ick.
  162.      */
  163.     if (thing == NOTHING)
  164.     return;
  165.     
  166.     switch (Typeof(thing)) {
  167.       case TYPE_ROOM:        /* Tell all players room has gone away */
  168.     notify_except(db[thing].contents, 0,
  169.               "The floor disappears under your feet, you fall through NOTHINGness and then:");
  170.     break;
  171.       case TYPE_PLAYER:        /* Show them where they arrived */
  172.     enter_room(thing, HOME);
  173.     break;
  174.     }
  175. }
  176. #endif /* DESTROY */
  177.  
  178. void notify_check(player, msg, no_puppet)
  179.      dbref player;
  180.      const char *msg;
  181.      int no_puppet;
  182. {
  183.     /* we only echo puppet messages if the puppet is in a different room
  184.      * from its owner, or we're explicitly told that puppet echo is okay.
  185.      */
  186.     
  187.     ATTR *d;
  188.     char tbuf1[BUFFER_LEN];
  189.     char *bp, *inpref;
  190.     
  191.     if ((player < 0) || (player >= db_top))
  192.     return;
  193.     if (depth++ > 7) {
  194.     depth--;
  195.     return;
  196.     }
  197.     
  198.     switch (Typeof(player)) {
  199.       case TYPE_ROOM:
  200.       case TYPE_EXIT:
  201.     depth--;
  202.     return;
  203.     break;            /* NOTREACHED */
  204.       case TYPE_PLAYER:
  205.     raw_notify(player, msg);
  206. #ifndef PLAYER_LISTEN
  207.     depth--;
  208.     return;
  209. #endif                /* PLAYER_LISTEN */
  210.     break;
  211.       case TYPE_THING:
  212.     if ((Toggles(player) & THING_PUPPET) &&
  213.         (!no_puppet || (Location(player) != Location(Owner(player))))) {
  214.         bp = tbuf1;
  215.         safe_str(Name(player), tbuf1, &bp);
  216.         safe_chr('>', tbuf1, &bp);
  217.         safe_chr(' ', tbuf1, &bp);
  218.         safe_str(msg, tbuf1, &bp);
  219.         *bp = '\0';
  220.         raw_notify(db[player].owner, tbuf1);
  221.     }
  222.     }
  223.     
  224.     /* do @listen stuff */
  225.     d = atr_get_noparent(player, "LISTEN");
  226.     if (d) {
  227.     strcpy(tbuf1, uncompress(d->value));
  228.     if(wild_match(tbuf1, msg)) {
  229.         if (speaker != player)
  230.         did_it(speaker,player, 0, NULL, 0, NULL, "AHEAR", NOTHING);
  231.         else
  232.         did_it(speaker, player, 0, NULL, 0, NULL, "AMHEAR", NOTHING);
  233.         did_it(speaker, player, 0, NULL, 0, NULL, "AAHEAR", NOTHING);
  234.         
  235.         /* also pass the message on
  236.          * Note: not telling player protects against two forms
  237.          * of recursion:
  238.          * player doesn't tell itself (as container) or as contents
  239.          * using teleport it is possible to create a recursive loop
  240.          * but this will be terminated when the depth variable exceeds 30
  241.          */
  242.         
  243.         if (!member(speaker, db[player].contents) &&
  244.         !filter_found(player, msg, 1)) {
  245.         d = atr_get(player, "INPREFIX");
  246.         if (d) {
  247.             strcpy(tbuf1, uncompress(d->value));
  248.             inpref = exec(player, speaker,
  249.                   EV_STRIP | EV_FCHECK, tbuf1);
  250.             bp = tbuf1;
  251.             safe_str(inpref, tbuf1, &bp);
  252.             safe_chr(' ', tbuf1, &bp);
  253.             safe_str(msg, tbuf1, &bp);
  254.             *bp = '\0';
  255.             free(inpref);
  256.         }
  257.         if (IS(player, TYPE_THING, THING_PUPPET))
  258.             notify_except2(db[player].contents, player, Owner(player),
  259.                    (d) ? tbuf1 : msg);
  260.         else
  261.             notify_except(db[player].contents, player,
  262.                   (d) ? tbuf1 : msg);
  263.         } 
  264.     } 
  265.     }
  266.     
  267.     /* if object is flagged LISTENER, check for ^ listen patterns
  268.      * these are like AHEAR - object cannot trigger itself.
  269.      * unlike normal @listen, don't pass the message on.
  270.      */
  271.     if ((speaker != player) && (IS(player, TYPE_THING, THING_LISTEN)))
  272.     atr_comm_match(player, speaker, '^', ':', msg, 0);
  273.     
  274.     depth--;
  275. }
  276.  
  277. #ifdef HAS_RUSAGE
  278. void rusage_stats()
  279. {
  280.     struct rusage usage;
  281.     int pid, psize;
  282.     
  283.     pid = getpid();
  284.     psize = getpagesize();
  285.     getrusage(RUSAGE_SELF, &usage);
  286.     
  287.     fprintf(stderr, "\nProcess statistics:\n");
  288.     fprintf(stderr, "Time used:   %10d user   %10d sys\n",
  289.         usage.ru_utime.tv_sec, usage.ru_stime.tv_sec);
  290.     fprintf(stderr, "Max res mem: %10d pages  %10d bytes\n",
  291.         usage.ru_maxrss, (usage.ru_maxrss * psize));
  292.     fprintf(stderr, "Integral mem:%10d shared %10d private %10d stack\n",
  293.         usage.ru_ixrss, usage.ru_idrss, usage.ru_isrss);
  294.     fprintf(stderr, "Page faults: %10d hard   %10d soft    %10d swapouts\n",
  295.         usage.ru_majflt, usage.ru_minflt, usage.ru_nswap);
  296.     fprintf(stderr, "Disk I/O:    %10d reads  %10d writes\n",
  297.         usage.ru_inblock, usage.ru_oublock);
  298.     fprintf(stderr, "Network I/O: %10d in     %10d out\n",
  299.         usage.ru_msgrcv, usage.ru_msgsnd);
  300.     fprintf(stderr, "Context swi: %10d vol    %10d forced\n",
  301.         usage.ru_nvcsw, usage.ru_nivcsw);
  302.     fprintf(stderr, "Signals:     %10d\n", usage.ru_nsignals);
  303. }
  304. #endif                /* HAS_RUSAGE */
  305.  
  306. void do_shutdown(player)
  307.      dbref player;
  308. {
  309.     if (Wizard(player)) {
  310.     raw_broadcast(0, "GAME: Shutdown by %s", db[player].name);
  311.     do_log(LT_ERR, player, NOTHING, "SHUTDOWN by %s\n", 
  312.            unparse_object(player, player));
  313.     
  314.     /* This will create a file used to check if a restart should occur */
  315. #ifdef AUTORESTART
  316.     system("touch NORESTART");
  317. #endif
  318.     
  319.     shutdown_flag = 1;
  320.     } else {
  321.     notify(player, "Your delusions of grandeur have been duly noted.");
  322.     }
  323. }
  324.  
  325. #ifdef XENIX
  326. /* rename hack!!! */
  327. rename(s1, s2)
  328.      char *s1;
  329.      char *s2;
  330. {
  331.     char buff[300];
  332.     sprintf(buff, "mv %s %s", s1, s2);
  333.     system(buff);
  334. }
  335. #endif
  336.  
  337. static void dump_database_internal()
  338. {
  339.     char tmpfl[2048];
  340.     FILE *f;
  341.     extern int unlink();
  342.     
  343.     sprintf(tmpfl, "%s.#%d#", dumpfile, epoch - 1);
  344.     unlink(tmpfl);        /* nuke our predecessor */
  345.     
  346.     sprintf(tmpfl, "%s.#%d#", dumpfile, epoch);
  347. #ifdef DBCOMP
  348.     if ((f = popen(tprintf("%s >%s", options.compress, tmpfl), "w")) != NULL) {
  349.     if (paranoid_dump)
  350.         db_paranoid_write(f);
  351.     else
  352.         db_write(f);
  353.     pclose(f);
  354.     if (rename(tmpfl, dumpfile) < 0)
  355.         perror(tmpfl);
  356.     } else
  357.     perror(tmpfl);
  358. #ifdef USE_MAILER
  359.     sprintf(tmpfl, "%s.#%d#", options.mail_db, epoch - 1);
  360.     unlink(tmpfl);
  361.     sprintf(tmpfl, "%s.#%d#", options.mail_db, epoch);
  362.     if (mdb_top >= 0)
  363.     if ((f = 
  364.          popen(tprintf("%s >%s", options.compress, tmpfl), "w")) != NULL) {
  365.         dump_mail(f);
  366.         pclose(f);
  367.         if (rename(tmpfl, options.mail_db) < 0)
  368.         perror(tmpfl);
  369.     } else
  370.         perror(tmpfl);
  371. #endif                /* USE_MAILER */
  372. #ifdef ALLOW_RPAGE
  373.     sprintf(tmpfl, "rpage.db.Z.#%d#", epoch - 1);
  374.     unlink(tmpfl);
  375.     sprintf(tmpfl, "rpage.db.Z.#%d#", epoch);
  376.     if ((f = popen(tprintf("%s >%s", options.compress, tmpfl), "w")) != NULL) {
  377.     dump_server_database(f);
  378.     pclose(f);
  379.     if (rename(tmpfl, "rpage.db.Z") < 0)
  380.         perror(tmpfl);
  381.     } else
  382.     perror(tmpfl);
  383. #endif                /* ALLOW_RPAGE */
  384. #else                /* DBCOMP */
  385.     if ((f = fopen(tmpfl, "w")) != NULL) {
  386.     if (paranoid_dump)
  387.         db_paranoid_write(f);
  388.     else
  389.         db_write(f);
  390.     fclose(f);
  391.     if (rename(tmpfl, dumpfile) < 0)
  392.         perror(tmpfl);
  393.     } else
  394.     perror(tmpfl);
  395. #ifdef USE_MAILER
  396.     sprintf(tmpfl, "%s.#%d#", options.mail_db, epoch - 1);
  397.     unlink(tmpfl);
  398.     sprintf(tmpfl, "%s.#%d#", options.mail_db, epoch);
  399.     if ((f = fopen(tmpfl, "w")) != NULL) {
  400.     dump_mail(f);
  401.     fclose(f);
  402.     if (rename(tmpfl, options.mail_db) < 0)
  403.         perror(tmpfl);
  404.     } else
  405.     perror(tmpfl);
  406. #endif                /* USE_MAILER */
  407. #ifdef ALLOW_RPAGE
  408.     sprintf(tmpfl, "rpage.db.#%d#", epoch - 1);
  409.     unlink(tmpfl);
  410.     sprintf(tmpfl, "rpage.db.#%d#", epoch);
  411.     if ((f = fopen(tmpfl, "w")) != NULL) {
  412.     dump_server_database(f);
  413.     fclose(f);
  414.     if (rename(tmpfl, "rpage.db") < 0)
  415.         perror(tmpfl);
  416.     } else
  417.     perror(tmpfl);
  418. #endif                /* ALLOW_RPAGE */
  419. #endif                /* DB_COMP */
  420. }
  421.  
  422. void panic(message)
  423.      const char *message;
  424. {
  425.     const char *panicfile = options.crash_db;
  426.     FILE *f;
  427.     int i;
  428.     
  429.     fprintf(stderr, "PANIC: %s\n", message);
  430.     report();
  431.     raw_broadcast(0, "EMERGENCY SHUTDOWN: %s", message);
  432.     
  433.     /* turn off signals */
  434.     for (i = 0; i < NSIG; i++) {
  435.     signal(i, SIG_IGN);
  436.     }
  437.     
  438.     /* shut down interface */
  439.     emergency_shutdown();
  440.     
  441.     /* dump panic file */
  442.     if ((f = fopen(panicfile, "w")) == NULL) {
  443.     perror("CANNOT OPEN PANIC FILE, YOU LOSE");
  444.     _exit(135);
  445.     } else {
  446.     fprintf(stderr, "DUMPING: %s\n", panicfile);
  447.     db_write(f);
  448.     fclose(f);
  449.     fprintf(stderr, "DUMPING: %s (done)\n", panicfile);
  450.     _exit(136);
  451.     }
  452. }
  453.  
  454. void dump_database()
  455. {
  456.     epoch++;
  457.     
  458.     fprintf(stderr, "DUMPING: %s.#%d#\n", dumpfile, epoch);
  459.     dump_database_internal();
  460.     fprintf(stderr, "DUMPING: %s.#%d# (done)\n", dumpfile, epoch);
  461. }
  462.  
  463. static int reaper()
  464. {
  465.     union wait my_stat;
  466.  
  467.     while (wait3(&my_stat, WNOHANG, 0) > 0)
  468.          ;
  469.  
  470.     signal(SIGCLD, (void *)reaper);
  471. }
  472.  
  473. void fork_and_dump()
  474. {
  475.     int child;
  476.     epoch++;
  477.     
  478.     fprintf(checklog_fp, "CHECKPOINTING: %s.#%d#\n", dumpfile, epoch);
  479.     fflush(checklog_fp);
  480. #ifndef NO_FORK
  481. #ifdef USE_VFORK
  482.     raw_broadcast(0, DUMP_NOFORK_MESSAGE);
  483.     child = vfork();
  484. #else                /* USE_VFORK */
  485.     child = fork();
  486. #endif                /* USE_VFORK */
  487. #else                /* NO FORK */
  488.     raw_broadcast(0, DUMP_NOFORK_MESSAGE);
  489.     child = 0;
  490. #endif                /* NO_FORK */
  491.     if (child == 0) {
  492.     /* in the child */
  493.     close(reserved);        /* get that file descriptor back */
  494. #ifdef CONCENTRATOR
  495. #ifndef XENIX
  496.     signal(SIGCHLD, SIG_DFL);
  497. #else
  498.     signal(SIGCLD, SIG_DFL);
  499. #endif  /* XENIX */
  500. #endif  /* CONCENTRATOR */
  501.     dump_database_internal();
  502. #ifndef NO_FORK
  503.     _exit(0);            /* !!! */
  504. #else                /* NO FORK */
  505.     reserved = open("/dev/null", O_RDWR);
  506. #ifdef CONCENTRATOR
  507. #ifndef XENIX
  508.     signal(SIGCHLD, (void *) reaper);
  509. #else
  510.     signal(SIGCLD, (void *) reaper);
  511. #endif    /* XENIX */
  512. #endif    /* CONCENTRATOR */
  513. #endif    /* NO_FORK */
  514.     } else if (child < 0) {
  515.     perror("fork_and_dump: fork()");
  516.     }
  517. }
  518.  
  519. void do_restart()
  520. {
  521.     dbref thing;
  522.     ATTR *s;
  523.     char *r;
  524.     char buf[SBUF_LEN];
  525.  
  526.     /* Do stuff that needs to be done for players only: add stuff to the
  527.      * alias table, and refund money from queued commands at shutdown.
  528.      */
  529.     for (thing = 0; thing < db_top; thing++) {
  530.     if (Typeof(thing) == TYPE_PLAYER) {
  531.       if ((s = atr_get_noparent(thing, "ALIAS")) != NULL) {
  532.           strcpy(buf, uncompress(s->value));
  533.           add_player(thing, buf);
  534.       }
  535.       if ((s = atr_get_noparent(thing, "QUEUE")) != NULL) {
  536.           giveto(thing, QUEUE_COST * atoi(uncompress(s->value)));
  537.           atr_add(thing, "QUEUE", "", GOD, NOTHING);
  538.       }
  539.       }
  540.     }
  541.  
  542.     /* Once we load all that, then we can trigger the startups and 
  543.      * begin queueing commands. Also, let's make sure that we get
  544.      * rid of null names.
  545.      */
  546.     for (thing = 0; thing < db_top; thing++) {
  547.     if (Name(thing) == NULL) {
  548.         do_log(LT_ERR, NOTHING, NOTHING, "Null name on object #%d",
  549.            thing);
  550.         if (Going(thing))
  551.         SET(Name(thing), "Garbage");
  552.         else
  553.         SET(Name(thing), "XXXX");
  554.     }
  555.     if (!Going(thing) &&
  556.         (Flags(thing) & STARTUP) && !(Flags(thing) & HALT)) {
  557.         s = atr_get_noparent(thing, "STARTUP");
  558.         if (!s)
  559.         continue;        /* just in case */
  560.         r = safe_uncompress(s->value);
  561.         parse_que(thing, r, thing);
  562.         free(r);
  563.     }
  564.     }
  565. }
  566.  
  567. int init_game(conf)
  568.      const char *conf;
  569. {
  570.     FILE *f;
  571.     int a;
  572.     extern void init_timer();
  573.     extern void config_file_startup();
  574.     
  575.     const char *infile, *outfile;
  576. #ifdef USE_MAILER
  577.     const char *mailfile;
  578. #endif
  579.     
  580.     depth = 0;
  581.     
  582.     for (a = 0; a < 10; a++)
  583.     wptr[a] = NULL;
  584.     
  585.     /* set MUSH start time */
  586.     start_time = time((time_t *) 0);
  587.     fprintf(stderr, "MUSH restarted, PID %d, at %s\n", 
  588.         getpid(), ctime(&start_time));
  589.     
  590.     /* initialize all the hash tables: flags, functions, and attributes. */
  591.     init_flag_hashtab();
  592.     init_func_hashtab();
  593.     init_aname_hashtab();
  594.     
  595.     config_file_startup(conf);
  596.     
  597.     infile = options.input_db;
  598.     outfile = options.output_db;
  599. #ifdef USE_MAILER
  600.     mailfile = options.mail_db;
  601. #endif
  602.     
  603.     /* read small text files into cache */
  604.     fcache_init();
  605.     
  606. #ifdef DBCOMP
  607.     if ((f = 
  608.      popen(tprintf("%s < %s", options.uncompress, infile), "r")) == NULL)
  609.     return -1;
  610. #else
  611.     if ((f = fopen(infile, "r")) == NULL)
  612.     return -1;
  613. #endif
  614.     
  615.     /* ok, read it in */
  616.     fprintf(stderr, "LOADING: %s\n", infile);
  617.     if (db_read(f) < 0) {
  618.     fprintf(stderr, "ERROR LOADING\n");
  619.     return -1;
  620.     }
  621.     fprintf(stderr, "LOADING: %s (done)\n", infile);
  622.     
  623.     /* everything ok */
  624. #ifdef DBCOMP
  625.     pclose(f);
  626. #else
  627.     fclose(f);
  628. #endif
  629.     
  630.     /* complain about bad config options */
  631.     if (!GoodObject(PLAYER_START) || (Typeof(PLAYER_START) != TYPE_ROOM))
  632.     fprintf(stderr, "WARNING: Player_start (#%d) is NOT a room.\n",
  633.         PLAYER_START);
  634. #ifdef DO_GLOBALS
  635.     if (!GoodObject(MASTER_ROOM) || (Typeof(MASTER_ROOM) != TYPE_ROOM))
  636.     fprintf(stderr, "WARNING: Master room (#%d) is NOT a room.\n",
  637.         MASTER_ROOM);
  638. #endif                /* DO_GLOBALS */
  639. #ifdef GUEST_RESTRICT
  640.     if (!GoodObject(GUEST_PLAYER) || (Typeof(GUEST_PLAYER) != TYPE_PLAYER))
  641.     fprintf(stderr, "WARNING: Guest player (#%d) is NOT a player.\n",
  642.         GUEST_PLAYER);
  643. #endif                /* GUEST_RESTRICT */
  644.     
  645. #ifdef USE_MAILER
  646.     /* read mail database */
  647. #ifdef DBCOMP
  648.     f = popen(tprintf("%s < %s", options.uncompress, mailfile), "r");
  649.     if (f == NULL)
  650.     mail_init();
  651. #else                /* DBCOMP */
  652.     f = fopen(mailfile, "r");
  653.     if (f == NULL)
  654.     mail_init();
  655. #endif                /* DBCOMP */
  656.     
  657.     /* okay, read it in */
  658.     else {
  659.     fprintf(stderr, "LOADING: %s\n", mailfile);
  660.     load_mail(f);
  661.     fprintf(stderr, "LOADING: %s (done)\n", mailfile);
  662. #ifdef DBCOMP
  663.     pclose(f);
  664. #else                /* DBCOMP */
  665.     fclose(f);
  666. #endif           /* DBCOMP */
  667.     }
  668.  
  669. #endif             /* USE_MAILER */
  670.     
  671. #ifdef ADD_NO_COMMAND_FLAG
  672.     /* futz with the database to add the new NO_COMMAND flag.
  673.      * By default, it's probably best to set this on rooms and players,
  674.      * since they get checked for $commands a lot but rarely get a match.
  675.      * Individual players can unset the flag manually if they need to
  676.      * match commands.
  677.      */
  678.     for (a = 0; a < db_top; a++) {
  679.     if ((Typeof(a) == TYPE_ROOM) || (Typeof(a) == TYPE_PLAYER))
  680.         db[a].flags |= NO_COMMAND;
  681.     }
  682. #endif
  683.     
  684.     /* set up the chat system table */
  685. #if (CHAT_SYSTEM >= 2)
  686.     init_chat();
  687. #endif                /* CHAT_SYSTEM */
  688.     
  689.     /* now do the rpage stuff */
  690. #ifdef ALLOW_RPAGE
  691.     rpage_init();
  692. #endif                /* ALLOW_RPAGE */
  693.     
  694.     /* initialize random number generator */
  695.     srandom(getpid());
  696.     
  697.     /* set up dumper */
  698.     strcpy(dumpfile, outfile);
  699.     init_timer();
  700. #ifndef XENIX
  701.     signal(SIGCHLD, (void *)reaper);
  702. #else                /* xenix */
  703.     signal(SIGCLD, (void *)reaper);
  704. #endif
  705.     
  706.     /* everything else ok. Restart all objects. */
  707.     do_restart();
  708.     return 0;
  709. }
  710.  
  711. static void do_readcache(player)
  712.      dbref player;
  713. {
  714.     if (!Wizard(player)) {
  715.     notify(player, "Permission denied.");
  716.     return;
  717.     }
  718.     fcache_load(player);
  719. }
  720.  
  721. #if (CHAT_SYSTEM >= 2)
  722. static int parse_chat(player, command)
  723.      dbref player;
  724.      char *command;
  725. {
  726.     /* function hacks up something of the form "+<channel> <message",
  727.      * finding the two args, and passes it to do_chat
  728.      */
  729.     
  730.     char *arg1;
  731.     char *arg2;
  732.     char tbuf1[MAX_COMMAND_LEN];
  733.     char *s;
  734.     channel_type chan;
  735.     
  736.     strcpy(tbuf1, command);    /* don't hack it up */
  737.     s = tbuf1;
  738.     
  739.     arg1 = s;
  740.     while (*s && !isspace(*s))
  741.     s++;
  742.     
  743.     if (*s) {
  744.     *s++ = '\0';
  745.     while (*s && isspace(*s))
  746.         s++;
  747.     }
  748.     arg2 = s;
  749.     
  750.     chan = find_channel(arg1);
  751.     if (!chan)            /* not valid channel, go parse command */
  752.     return 0;
  753.     else {
  754.     do_chat(player, chan, arg2);
  755.     return 1;
  756.     }
  757. }
  758. #endif                /* CHAT_SYSTEM */
  759.  
  760. static void set_interp(player, cause, obj, attrib, val, from_port)
  761.      dbref player;
  762.      dbref cause;
  763.      char *obj;
  764.      char *attrib;
  765.      char *val;
  766.      int from_port;
  767. {
  768.     /* Set of the format &attr, @attr, or @_attr.
  769.      * We need to know if something was directly typed in so we don't
  770.      * put it through our interpreter.
  771.      */
  772.     
  773.     char tbuf1[BUFFER_LEN];
  774.     char *name = NULL;
  775.     char *ptr = NULL;
  776.     int need_free = 0;
  777.     char *bp;
  778.     
  779.     name = exec(player, cause, EV_STRIP | EV_FCHECK, obj);
  780.     
  781.     if (*val) {
  782.     if (from_port) {
  783.         /* just strip off a layer of braces and don't interpret */
  784.         ptr = parse_to(&val, '\0', 0);
  785.     } else {
  786.         ptr = exec(player, cause, EV_STRIP | EV_FCHECK, val);
  787.         need_free = 1;
  788.     }
  789.     } else {
  790.     ptr = val;
  791.     }
  792.     
  793.     bp = tbuf1;
  794.     safe_str(attrib, tbuf1, &bp);
  795.     safe_chr(':', tbuf1, &bp);
  796.     safe_str(ptr, tbuf1, &bp);
  797.     *bp = '\0';
  798.     do_set(player, name, tbuf1);
  799.     
  800.     if (name)
  801.     free(name);
  802.     if (need_free) {
  803.     free(ptr);
  804. #ifdef MEM_CHECK
  805.     del_check("exec.buff");
  806. #endif
  807.     }
  808. }
  809.  
  810. int test_set(player, cause, command, arg1, arg2, from_port)
  811.      dbref player;
  812.      dbref cause;
  813.      char *command;
  814.      char *arg1;
  815.      char *arg2;
  816.      int from_port;
  817. {
  818.     /* check for an attribute set using @attr or &attr */
  819.     
  820.     ATTR *atrp;
  821.     char *atrname = NULL;
  822.     
  823.     if (command[0] != '@' && command[0] != '&')
  824.     return (0);
  825.     
  826.     /* added to make this 2.0 compatible. with '&' equivalent to '@_' */
  827.     if ((command[0] == '&') && (command[1] != '\0')) {
  828.     atrname = exec(player, cause, EV_EVAL | EV_FCHECK, command + 1);
  829.     set_interp(player, cause, arg1, atrname, arg2, from_port);
  830.     if (atrname)
  831.         free(atrname);
  832.     return (1);
  833.     }
  834.     
  835.     /* first character is '@' */
  836.     
  837.     /* check if it's a regular attribute */
  838.     
  839.     atrp = atr_match(strupper(command + 1));
  840.     if (atrp != NULL) {
  841.     set_interp(player, cause, arg1, atrp->name, arg2, from_port);
  842.     return (1);
  843.     }
  844.     
  845.     /* else treat it as a user-defined one */
  846.     if((command[1] != '_') || (command[2] == '\0'))
  847.     return (0);
  848.     
  849.     atrname = exec(player, cause, EV_EVAL | EV_FCHECK, command + 1);
  850.     set_interp(player, cause, arg1, command + 2, arg2, from_port);
  851.     if (atrname)
  852.     free(atrname);
  853.     return (1);
  854. }
  855.  
  856. char **argv_hack(player, cause, arg, fargs, eflags)
  857.      dbref player;
  858.      dbref cause;
  859.      char *arg;
  860.      char *fargs[];
  861.      int eflags;
  862. {
  863.     char *xargs[MAX_ARG];
  864.     int i;
  865.     
  866.     if (!arg || !*arg) {        /* make sure there's something to parse */
  867.     for (i = 0; i < MAX_ARG; i++)
  868.         fargs[i] = NULL;
  869.     return fargs;
  870.     }
  871.     
  872.     parse_arglist(player, cause, arg, '\0', eflags, xargs, MAX_ARG);
  873.     
  874.     /* because somebody braindamaged decided, way back when, that
  875.      * argv command lists were going to start at argv[1], we have
  876.      * to do a thoroughly inelegant copy.
  877.      */
  878.     
  879.     for (i = 0; i < MAX_ARG - 1; i++) {
  880.     fargs[i + 1] = xargs[i];
  881.     }
  882.     
  883.     if (xargs[MAX_ARG - 1]) {    /* extra we can't use */
  884.     free(xargs[MAX_ARG - 1]);
  885. #ifdef MEM_CHECK
  886.     del_check("exec.buff");
  887. #endif
  888.     }
  889.     
  890.     return fargs;
  891. }
  892.  
  893. /*
  894.  * use this only in process_command
  895.  */
  896. #define Matched(string) { if(!string_prefix((string), command)) goto bad; }
  897. #define IfSwitch(string)  if (string_prefix((string), slashp))
  898. #define arg1      buf1 = exec(player, cause, EV_STRIP | EV_FCHECK, buf2)
  899. #define arg2      saveptr = exec(player, cause, EV_STRIP | EV_FCHECK, arg)
  900. #define argu      saveptr = exec(player, cause, EV_STRIP | EV_FCHECK, buff3)
  901. #define argv      argv_hack(player, cause, arg, fargs, EV_EVAL | EV_STRIP)
  902. #define vargs     argv_hack(player, cause, arg, fargs, EV_STRIP)
  903.  
  904. #define list_match(x)        list_check(x, player, '$', ':', cptr, 0)
  905. #define cmd_match(x)         atr_comm_match(x, player, '$', ':', cptr, 0);
  906.  
  907. void process_command(player, command, cause, from_port)
  908.      dbref player;
  909.      char *command;
  910.      dbref cause;
  911.      int from_port;        /* 1 if this is direct input from a port
  912.                  * (i.e. typed directly by a player).
  913.                  * attrib sets don't get parsed then.
  914.                  */
  915. {
  916.     int a;
  917.     char *q;            /* utility */
  918.     char *p;            /* utility */
  919.     
  920.     char *fargs[MAX_ARG];
  921.     char buff3[BUFFER_LEN];
  922.     char unp[BUFFER_LEN];        /* unparsed command */
  923.     /* general form command arg0=arg1,arg2...arg10 */
  924.     int gagged = 0;
  925.     char temp[BUFFER_LEN];        /* utility */
  926.     int i;                        /* utility */
  927.     char *slashp = NULL;
  928.     char tchar;
  929.     char *buf1 = NULL;
  930.     char *buf2 = NULL;
  931.     char *arg = NULL;
  932.     char *saveptr = NULL;
  933.     char *cptr = NULL;
  934.     
  935.     void do_poor();
  936.     void do_version(), do_dolist(), do_config(), do_uptime(), do_scan();
  937.     
  938.     for (a = 0; a < MAX_ARG; a++)
  939.     fargs[a] = NULL;
  940.     
  941.     depth = 0;
  942.     if (command == 0) {
  943.     do_log(LT_ERR, NOTHING, NOTHING, "ERROR: No command!!!");
  944.     return;
  945.     }
  946.     
  947. #ifdef NEVER
  948.     /* Why was this being done??? It makes no sense. */
  949. #ifndef HPUX
  950.     /* just to have fun, let's reinit the random number gen (with the time) */
  951.     srandom((int)time((time_t *) 0));
  952. #endif                /* HPUX */
  953. #endif                /* NEVER */
  954.     
  955.     /*  This check removed because it's a little extreme. For example,
  956.      *  someone looking at God ought to be able to trigger his @adesc.
  957.      
  958.      if (God(player) && !God(cause))
  959.      return;
  960.      */
  961.     
  962.     /* robustify player */
  963.     if ((player < 0) || (player >= db_top)) {
  964.     fprintf(stderr, "ERROR: bad player %d in process_command\n", player);
  965.     return;
  966.     }
  967.     
  968.     gagged = IS(db[player].owner, TYPE_PLAYER, PLAYER_GAGGED);
  969.     /* Access the player */
  970.     Access(player);
  971.     
  972.     /* Halted or destroyed objects can't execute commands */
  973.     if ((Typeof(player) != TYPE_PLAYER) &&
  974.     ((Flags(player) & GOING) || (Flags(player) & HALT))) {
  975.     notify(Owner(player),
  976.            tprintf("Attempt to execute command by halted object #%d",
  977.                player));
  978.     return;
  979.     }
  980.     
  981.     /* Players and things should not have invalid locations. This check
  982.      * must be done _after_ the destroyed-object check.
  983.      */
  984.     if ((!GoodObject(Location(player)) || 
  985.      ((Flags(Location(player)) & GOING) && 
  986.       (Typeof(Location(player)) != TYPE_ROOM))) && Mobile(player)) {
  987.     notify(Owner(player),
  988.            tprintf("Invalid location on command execution: %s(#%d)",
  989.                Name(player), player));
  990.     do_log(LT_ERR, NOTHING, NOTHING, 
  991.            "Command attempted by %s(#%d) in invalid location #%d.",
  992.            Name(player), player, Location(player));
  993.     moveto(player, PLAYER_START); /* move it someplace valid */
  994.     }
  995.     
  996.     /* The following check is removed due to a security hole it causes!
  997.      * 'If player is an exit or room execute command as owner'
  998.      */
  999.     /* if ((Typeof(player) == TYPE_ROOM) || (Typeof(player) == TYPE_EXIT))
  1000.        player = db[player].owner;  */
  1001.     speaker = player;
  1002.     
  1003.     if (options.log_commands || Suspect(player))
  1004.     do_log(LT_CMD, player, 0, "%s", command);
  1005.     
  1006.     if (Flags(player) & VERBOSE)
  1007.     raw_notify(Owner(player), tprintf("#%d] %s", player, command));
  1008.     
  1009.     /* clear our local registers */
  1010.     for (a = 0; a < 10; a++)
  1011.     *(rptr[a]) = '\0';
  1012.     
  1013.     /* reset the function invocation counter */
  1014.     invok_counter = 0;
  1015.     
  1016.     /* eat leading whitespace */
  1017.     while (*command && isspace(*command))
  1018.     command++;
  1019.     /* eat extra white space */
  1020.     q = p = command;
  1021.     while (*p) {
  1022.     /* scan over word */
  1023.     while (*p && !isspace(*p))
  1024.         *q++ = *p++;
  1025.     /* smash spaces */
  1026.     while (*p && isspace(*++p)) ;
  1027.     if (*p)
  1028.         *q++ = ' ';        /* add a space to separate next word */
  1029.     }
  1030.     /* terminate */
  1031.     *q = '\0';
  1032.     
  1033.     /* ignore null commands that aren't from players */
  1034.     if ((!command || !*command) && !from_port)
  1035.     return;
  1036.     
  1037.     /* important home checking comes first! */
  1038.     if (strcmp(command, "home") == 0) {
  1039.     if(Typeof(player) == TYPE_EXIT || Typeof(player) == TYPE_ROOM)
  1040.         return;
  1041.     do_move(player, command, 0);
  1042.     return;
  1043.     }
  1044.     
  1045.     /* check for forces of the format: "#100 :do this." */
  1046.     if (!gagged && Mobile(player) && (*command == '#') &&
  1047.     force_by_number(player, command))
  1048.     return;
  1049.     
  1050.     /* check for single-character commands */
  1051.     if (*command == SAY_TOKEN && !gagged) {
  1052.     buf1 = exec(player, cause, EV_STRIP | EV_FCHECK, command + 1);
  1053.     do_say(player, buf1);
  1054.     } else if (*command == POSE_TOKEN && !gagged) {
  1055.     buf1 = exec(player, cause, EV_STRIP | EV_FCHECK, command + 1);
  1056.     do_pose(player, buf1, 0);
  1057.     } else if (*command == SEMI_POSE_TOKEN && !gagged) {
  1058.     buf1 = exec(player, cause, EV_STRIP | EV_FCHECK, command + 1);
  1059.     do_pose(player, buf1, 1);
  1060. #if (CHAT_SYSTEM >= 2)
  1061.     } else if (*command == CHAT_TOKEN && !gagged && 
  1062.            parse_chat(player, command + 1)) {
  1063.     /* the parse_chat function will take care of doing the chat messages
  1064.      * if a channel is found. Otherwise, we want to go on.
  1065.      */
  1066.     return;
  1067. #endif                /* CHAT_SYSTEM */
  1068.     /* now check if command is an exact match for an exit in the room */
  1069.     } else if (can_move(player, command)) {
  1070.     if (!Mobile(player))
  1071.         return;
  1072.     do_move(player, command, 0);
  1073.     } else {
  1074.     strcpy(unp, command);
  1075.     
  1076.     /* parse arguments */
  1077.     
  1078.     /* split command from arguments */
  1079.     /* move over command word */
  1080.     for (arg = command; *arg && !isspace(*arg); arg++)
  1081.         ;
  1082.     /* truncate command */
  1083.     if (*arg)
  1084.         *arg++ = '\0';
  1085.     
  1086.     /* grab switches and strip them off, truncating command, unless
  1087.      * the first character of the command is a '&'. That indicates
  1088.          * an attribute set; in order to avoid clobbering functions
  1089.          * like 'get' which use a slash (and because we can't give
  1090.          * switches to an &-attribute set anyway), we don't grab switches.
  1091.      */
  1092.     if (*command != '&') {
  1093.         slashp = (char *) index(command, '/');
  1094.         if (slashp)
  1095.         *slashp++ = '\0';
  1096.     }
  1097.     
  1098.     /* move over spaces */
  1099.     while (*arg && isspace(*arg))
  1100.         arg++;
  1101.     
  1102.     strcpy(buff3, arg);        /* save it for news */
  1103.     
  1104.     buf2 = parse_to(&arg, '=', 0);
  1105.     
  1106.     /* Don't choke when no '=' was specified */
  1107.     if (!arg || (arg && !*arg)) {
  1108.         arg = &tchar;
  1109.         *arg = '\0';
  1110.     }
  1111.     
  1112.     if (!gagged && test_set(player, cause, command, buf2, arg, from_port)) {
  1113.         /* we don't need to free any memory. It's been done for us. */
  1114.         return;
  1115.     }
  1116.     
  1117.     /* Just as a reminder of what all these variables mean:
  1118.      *
  1119.      * arg1, arg2, argu, and argv are all macros. They evaluate to
  1120.      * pronoun-substituted versions of the left hand side of the = sign,
  1121.      * right hand side of the = sign, the full expression regardless of
  1122.      * = sign, and the parsed version of an argument list. 
  1123.      * vargs is a macro which makes an argument vector without parsing it.
  1124.      *
  1125.      * arg is the unparsed right-hand side of the equals sign.
  1126.      * buff3 is an unparsed version of the argument to the command.
  1127.      * unp is the full unparsed command.
  1128.      */
  1129.     
  1130.     /* now scan all the commands */
  1131.     switch (command[0]) {
  1132.       case '@':
  1133.         switch (command[1]) {
  1134.           case '@':
  1135.         /* dummy statement, '@@' is the comment signal.
  1136.          * since it's a comment, just ignore it.
  1137.          */
  1138.         break;
  1139.           case 'a':
  1140.           case 'A':
  1141.         if(!strcasecmp(command,"@allhalt")) {
  1142.             do_allhalt(player);
  1143.             break;
  1144.         }
  1145.         switch(command[2]) {
  1146. #ifdef QUOTA
  1147.           case 'l':
  1148.           case 'L':
  1149.             Matched("@allquota");
  1150.             do_allquota(player, arg1);
  1151.             break;
  1152. #endif /* QUOTA */
  1153.           case 't':
  1154.           case 'T':
  1155.             if(string_prefix("@atrlock", command)) {
  1156.             do_atrlock(player, arg1, arg2);
  1157.             } else {
  1158.             Matched("@atrchown");
  1159.             do_atrchown(player, arg1, arg2);
  1160.             }
  1161.             break;
  1162.           default:
  1163.             goto bad;
  1164.         }
  1165.         break;
  1166.           case 'b':
  1167.           case 'B':
  1168.         Matched("@boot");
  1169.         if (!slashp)
  1170.             do_boot(player, arg1, 0);
  1171.         else IfSwitch("port")
  1172.             do_boot(player, arg1, 1);
  1173.         else
  1174.             goto bad;
  1175.         break;
  1176.           case 'c':
  1177.           case 'C':
  1178.         /* chown, create */
  1179.         switch (command[2]) {
  1180.           case 'h':
  1181.           case 'H':
  1182.             switch (command[3]) {
  1183. #if (CHAT_SYSTEM >= 2)
  1184.               case 'a':
  1185.               case 'A':
  1186.             if (gagged) break;
  1187.             switch(command[4]) {
  1188.               case 'n':
  1189.               case 'N':
  1190.                 Matched("@channel");
  1191.                 if (!slashp)
  1192.                 do_channel(player, arg1, arg2);
  1193.                 else IfSwitch("who")
  1194.                 do_channel(player, arg1, "who");
  1195.                 else IfSwitch("wipe")
  1196.                 do_channel(player, arg1, "wipe");
  1197.           else IfSwitch("on")
  1198.             do_channel(player, arg1, "on");
  1199.           else IfSwitch("off")
  1200.             do_channel(player, arg1, "off");
  1201.           else IfSwitch("list")
  1202.             do_channel_list(player);
  1203.           else IfSwitch("add")
  1204.             do_chan_admin(player, arg1, arg2, 0);
  1205.           else IfSwitch("delete")
  1206.             do_chan_admin(player, arg1, arg2, 1);
  1207.           else IfSwitch("name")
  1208.             do_chan_admin(player, arg1, arg2, 2);
  1209.           else IfSwitch("priv")
  1210.             do_chan_admin(player, arg1, arg2, 3);
  1211.           else
  1212.             goto bad;
  1213.           break;
  1214.         case 't':
  1215.         case 'T':
  1216.           Matched("@chat");
  1217.           do_chat(player, find_channel(arg1), arg2);
  1218.           break;
  1219.         default:
  1220.           goto bad;
  1221.         }        /* command[4] */
  1222.         break;        /* case command[3] == 'a' */
  1223. #endif                /* CHAT_SYSTEM */
  1224.           case 'o':
  1225.           case 'O':
  1226.         if(!strcasecmp(command,"@chownall")) {
  1227.           do_chownall(player, arg1, arg2);
  1228.           break;
  1229.                 } else {
  1230.           if (gagged) break;
  1231.           Matched("@chown");
  1232.           do_chown(player, arg1, arg2);
  1233.           break;
  1234.         }
  1235.           case 'z':
  1236.           case 'Z':
  1237.         if (!strcasecmp(command, "@chzoneall")) {
  1238.           do_chzoneall(player, arg1, arg2);
  1239.           break;
  1240.         } else {
  1241.           if (gagged) break;
  1242.           Matched("@chzone");
  1243.           do_chzone(player, arg1, arg2);
  1244.           break;
  1245.         }
  1246.           }
  1247.           break;
  1248.           case 'o':
  1249.           case 'O':
  1250.             Matched("@config");
  1251.             if (!slashp)
  1252.           do_config(player, 0);
  1253.             else IfSwitch("globals")
  1254.           do_config(player, 1);
  1255.             else IfSwitch("defaults")
  1256.           do_config(player, 0);
  1257.             else IfSwitch("costs")
  1258.           do_config(player, 2);
  1259.             else IfSwitch("functions")
  1260.           do_list_functions(player);
  1261.             else
  1262.           goto bad;
  1263.             break;
  1264.             case 'p':
  1265.           case 'P':
  1266.             Matched("@cpattr");
  1267.             do_cpattr(player, arg1, argv);
  1268.             break;
  1269.           case 'r':
  1270.           case 'R':
  1271.         if (gagged)
  1272.           break;
  1273.         Matched("@create");
  1274.         do_create(player, arg1, atol(arg2));
  1275.         break;
  1276.           case 'l':
  1277.           case 'L':
  1278.         if (gagged)
  1279.           break;
  1280.         Matched("@clone");
  1281.         do_clone(player, arg1);
  1282.         break;
  1283.           default:
  1284.         goto bad;
  1285.         }
  1286.         break;
  1287.       case 'd':
  1288.       case 'D':
  1289.         /* daytime, dbck,  dig, or dump */
  1290.         switch (command[2]) {
  1291. #ifdef DESTROY
  1292.           case 'b':
  1293.           case 'B':
  1294.         Matched("@dbck");
  1295.         do_dbck(player);
  1296.         break;
  1297. #endif
  1298.           case 'E':
  1299.           case 'e':
  1300.         switch (command[3]) {
  1301.         case 'c':
  1302.         case 'C':
  1303.           Matched("@decompile");
  1304.           do_decompile(player, arg1);
  1305.           break;
  1306. #ifdef DESTROY
  1307.         case 's':
  1308.         case 'S':
  1309.           Matched("@destroy");
  1310.           if (!slashp)
  1311.             do_destroy(player, arg1, 0);
  1312.           else IfSwitch("override")
  1313.             do_destroy(player, arg1, 1);
  1314.           else
  1315.             goto bad;
  1316.           break;
  1317. #endif                /* DESTROY */
  1318.         default:
  1319.           goto bad;
  1320.         }
  1321.         break;
  1322.           case 'i':
  1323.           case 'I':
  1324.         switch (command[3]) {
  1325.         case 'g':
  1326.         case 'G':
  1327.           if (gagged)
  1328.             break;
  1329.           Matched("@dig");
  1330.           if (!slashp)
  1331.             do_dig(player, arg1, argv, 0);
  1332.           else IfSwitch("teleport")
  1333.             do_dig(player, arg1, argv, 1);
  1334.           else
  1335.             goto bad;
  1336.           break;
  1337.         case 's':
  1338.         case 'S':
  1339.           Matched("@disable");
  1340.           do_enable(player, arg1, 0);
  1341.           break;
  1342.         default:
  1343.           goto bad;
  1344.         }
  1345.         break;
  1346.           case 'o':
  1347.           case 'O':
  1348.         switch (command[3]) {
  1349. #ifdef AT_DOING
  1350.         case 'i':
  1351.         case 'I':
  1352.           if(gagged)
  1353.             break;
  1354.           if(Typeof(player) != TYPE_PLAYER)
  1355.             break;
  1356.           Matched("@doing");
  1357.           if (!slashp)
  1358.             do_doing(player, buff3);
  1359.           else IfSwitch("header")
  1360.             do_poll(player, buff3);
  1361.           else
  1362.             goto bad;
  1363.           break;
  1364. #endif
  1365.         case 'l':
  1366.         case 'L':
  1367.           Matched("@dolist");
  1368.           do_dolist(player, arg1, arg, cause, 0);
  1369.           break;
  1370.         default:
  1371.           goto bad;
  1372.         }
  1373.         break;
  1374.           case 'r':
  1375.           case 'R':
  1376.         Matched("@drain");
  1377.         do_notify(player, cause, 2, arg1, arg2);
  1378.         break;
  1379.           case 'u':
  1380.           case 'U':
  1381.         Matched("@dump");
  1382.         if (!slashp)
  1383.           do_dump(player, "", 0);
  1384.         else IfSwitch("paranoid")
  1385.           do_dump(player, arg1, 1);
  1386.         else
  1387.           goto bad;
  1388.         break;
  1389.           default:
  1390.         goto bad;
  1391.         }
  1392.         break;
  1393.       case 'E':
  1394.       case 'e':
  1395.         switch (command[2]) {
  1396.           case 'd':
  1397.           case 'D':
  1398.         if (gagged)
  1399.           break;
  1400.         Matched("@edit");
  1401.         do_gedit(player, arg1, vargs);
  1402.         break;
  1403.           case 'l':
  1404.           case 'L':
  1405.         if (gagged) break;
  1406.         Matched("@elock");
  1407.         do_lock(player, arg1, arg2, ENTERLOCK);
  1408.         break;
  1409.           case 'm':
  1410.           case 'M':
  1411.         if (gagged)
  1412.           break;
  1413.         Matched("@emit");
  1414.         if (!slashp)
  1415.           do_emit(player, argu);
  1416.         else IfSwitch("room")
  1417.           do_lemit(player, argu);
  1418.         else
  1419.           goto bad;
  1420.         break;
  1421.           case 'n':
  1422.           case 'N':
  1423.         if(gagged) break;
  1424.         switch (command[3]) {
  1425.         case 'a':
  1426.         case 'A':
  1427.           Matched("@enable");
  1428.           do_enable(player, arg1, 1);
  1429.           break;
  1430.         case 't':
  1431.         case 'T':
  1432.           Matched("@entrances");
  1433.           if (!slashp)
  1434.             do_entrances(player, arg1, argv, 0);
  1435.           else IfSwitch("exits")
  1436.             do_entrances(player, arg1, argv, 1);
  1437.           else IfSwitch("things")
  1438.             do_entrances(player, arg1, argv, 2);
  1439.             else IfSwitch("players")
  1440.             do_entrances(player, arg1, argv, 3);
  1441.           else IfSwitch("rooms")
  1442.             do_entrances(player, arg1, argv, 4);
  1443.           else
  1444.             goto bad;
  1445.           break;
  1446.         default:
  1447.           goto bad;
  1448.         }
  1449.         break;
  1450.           case 'u':
  1451.           case 'U':
  1452.         if (gagged) break;
  1453.         Matched("@eunlock");
  1454.         do_unlock(player, arg1, ENTERLOCK);
  1455.         break;
  1456.           default:
  1457.         goto bad;
  1458.         }
  1459.         break;
  1460.       case 'F':
  1461.       case 'f':
  1462.         /* find, or force */
  1463.         switch (command[2]) {
  1464.           case 'i':
  1465.           case 'I':
  1466.             switch (command[3]) {
  1467.         case 'n':
  1468.         case 'N':
  1469.           if (gagged)
  1470.             break;
  1471.           Matched("@find");
  1472.           do_find(player, arg1, argv);
  1473.           break;
  1474.         case 'x':
  1475.         case 'X':
  1476.           Matched("@fixdb");
  1477.           if (!slashp)
  1478.             goto bad;
  1479.           else IfSwitch("location")
  1480.             do_fixdb(player, arg1, arg2, 0);
  1481.           else IfSwitch("contents")
  1482.             do_fixdb(player, arg1, arg2, 1);
  1483.           else IfSwitch("exits")
  1484.             do_fixdb(player, arg1, arg2, 2);
  1485.           else IfSwitch("next")
  1486.             do_fixdb(player, arg1, arg2, 3);
  1487.           else
  1488.             goto bad;
  1489.           break;
  1490.         default:
  1491.           goto bad;
  1492.         }
  1493.         break;
  1494.           case 'o':
  1495.           case 'O':
  1496.         if (gagged)
  1497.           break;
  1498.         Matched("@force");
  1499.         do_force(player, arg1, arg2);
  1500.         break;
  1501.           case 'u':
  1502.           case 'U':
  1503.         if (gagged)
  1504.           break;
  1505.         Matched("@function");
  1506.         do_function(player, arg1, argv);
  1507.         break;
  1508.           default:
  1509.         goto bad;
  1510.         }
  1511.         break;
  1512.       case 'g':
  1513.       case 'G':
  1514.         if(gagged)
  1515.           break;
  1516.         switch (command[2]) {
  1517.         case 'e':
  1518.         case 'E':
  1519.           Matched("@gedit");
  1520.           do_gedit(player, arg1, vargs);
  1521.           break;
  1522.         case 'r':
  1523.         case 'R':
  1524.           Matched("@grep");
  1525.           if (!slashp)
  1526.         do_grep(player, arg1, arg, 0);
  1527.           else IfSwitch("list")
  1528.         do_grep(player, arg1, arg, 0);
  1529.           else IfSwitch("print")
  1530.         do_grep(player, arg1, arg, 1);
  1531.           else
  1532.         goto bad;
  1533.           break;
  1534.         default:
  1535.           goto bad;
  1536.       }
  1537.       break;
  1538.          case 'h':
  1539.      case 'H':
  1540.        switch (command[2]) {
  1541.          case 'a':
  1542.          case 'A':
  1543.            /* halt */
  1544.            Matched("@halt");
  1545.            if (!slashp)
  1546.            do_halt1(player, arg1, arg2);
  1547.            else IfSwitch("all")
  1548.            do_allhalt(player);
  1549.                else 
  1550.            goto bad;
  1551.            break;
  1552.          case 'i':
  1553.          case 'I':
  1554.            Matched("@hide");
  1555.            if (!slashp)
  1556.            hide_player(player, 1);
  1557.            else IfSwitch("no")
  1558.            hide_player(player, 0);
  1559.                else IfSwitch("yes")
  1560.            hide_player(player, 1);
  1561.                else
  1562.            goto bad;
  1563.            break;
  1564.          default:
  1565.            goto bad;
  1566.        }
  1567.            break;
  1568.       case 'k':
  1569.       case 'K':
  1570.         Matched("@kick");
  1571.         do_kick(player, arg1);
  1572.         break;
  1573.       case 'l':
  1574.       case 'L':
  1575.         /* lock or link */
  1576.         switch (command[2]) {
  1577.           case 'e':
  1578.           case 'E':
  1579.             if(gagged) break;
  1580.         Matched ("@lemit");
  1581.         do_lemit(player,arg1,arg2);
  1582.         break;
  1583.           case 'i':
  1584.           case 'I':
  1585.         if(gagged) break;
  1586.         if(string_prefix("@link", command)) {
  1587.           do_link(player, arg1, arg2);
  1588.           break;
  1589.         } else {
  1590.           Matched("@listmotd");
  1591.           do_motd(player, 3, "");
  1592.           break;
  1593.         }
  1594.           case 'o':
  1595.           case 'O':
  1596.         if (gagged) break;
  1597.         Matched("@lock");
  1598.         if (!slashp)
  1599.           do_lock(player, arg1, arg2, BASICLOCK);
  1600.         else IfSwitch("enter")
  1601.           do_lock(player, arg1, arg2, ENTERLOCK);
  1602.         else IfSwitch("tport")
  1603.           do_lock(player, arg1, arg2, ENTERLOCK);
  1604.         else IfSwitch("page")
  1605.           do_lock(player, arg1, arg2, USELOCK);
  1606.         else IfSwitch("use")
  1607.           do_lock(player, arg1, arg2, USELOCK);
  1608.         else
  1609.           goto bad;
  1610.         break;
  1611.           default:
  1612.         goto bad;
  1613.           }
  1614.         break;
  1615.       case 'm':
  1616.       case 'M':
  1617.         /* @mail, @map, @motd */
  1618.         switch (command[2]) {
  1619.         case 'a':
  1620.         case 'A':
  1621.           switch (command[3]) {
  1622.           case 'i':
  1623.           case 'I':
  1624. #ifdef USE_MAILER
  1625.         if(gagged) break;
  1626.         Matched("@mail");
  1627.         if (!slashp)
  1628.           do_mail(player, arg1, arg2);
  1629.         else IfSwitch("stats")
  1630.           do_mail_stats(player, arg1, 0);
  1631.         else IfSwitch("dstats")
  1632.           do_mail_stats(player, arg1, 1);
  1633.         else IfSwitch("fstats")
  1634.           do_mail_stats(player, arg1, 2);
  1635.         else IfSwitch("debug")
  1636.           do_mail_debug(player, arg1, arg2);
  1637.         else
  1638.           goto bad;
  1639.         break;
  1640. #endif
  1641.           case 'p':
  1642.           case 'P':
  1643.         Matched("@map");
  1644.         do_dolist(player, arg1, arg, cause, 1);
  1645.         break;
  1646.           default:
  1647.         goto bad;
  1648.           }
  1649.           break;
  1650.         case 'o':
  1651.         case 'O':
  1652.           if (gagged) break;
  1653.           Matched("@motd");
  1654.           if (!slashp)
  1655.         do_motd(player, 1, argu);
  1656.           else IfSwitch("connect")
  1657.         do_motd(player, 1, argu);
  1658.           else IfSwitch("list")
  1659.         do_motd(player, 3, "");
  1660.           else IfSwitch("wizard")
  1661.         do_motd(player, 2, argu);
  1662.           else IfSwitch("down")
  1663.         do_motd(player, 4, argu);
  1664.           else IfSwitch("full")
  1665.         do_motd(player, 5, argu);
  1666.           else
  1667.         goto bad;
  1668.           break;
  1669.         default:
  1670.           goto bad;
  1671.         }
  1672.         break;
  1673.       case 'n':
  1674.       case 'N':
  1675.         /* @name, @newpassword */
  1676.         switch (command[2]) {
  1677.           case 'a':
  1678.           case 'A':
  1679.         if (gagged)
  1680.           break;
  1681.         Matched("@name");
  1682.         do_name(player, arg1, arg2);
  1683.         break;
  1684.           case 'e':
  1685.           case 'E':
  1686.         if (strcmp(command, "@newpassword"))
  1687.           goto bad;
  1688.         do_newpassword(player, arg1, arg2);
  1689.         break;
  1690.           case 'o':
  1691.           case 'O':
  1692.         Matched("@notify");
  1693.         if (!slashp)
  1694.           do_notify(player, cause, 0, arg1, arg2);
  1695.         else IfSwitch("all")
  1696.           do_notify(player, cause, 1, arg1, arg2);
  1697.         else
  1698.           goto bad;
  1699.         break;
  1700. #ifdef DESTROY
  1701.           case 'u':
  1702.           case 'U':
  1703.         if (gagged) break;
  1704.         Matched("@nuke");
  1705.         do_destroy(player, arg1, 1);
  1706.         break;
  1707. #endif
  1708.           default:
  1709.         goto bad;
  1710.         }
  1711.         break;
  1712.       case 'o':
  1713.       case 'O':
  1714.         /* @oemit, @open */
  1715.         switch (command[2]) {
  1716.           case 'e':
  1717.           case 'E':
  1718.         if (gagged)
  1719.           break;
  1720.         Matched("@oemit");
  1721.         do_oemit(player, arg1, arg2);
  1722.         break;
  1723.           case 'p':
  1724.           case 'P':
  1725.             if (gagged)
  1726.               break;
  1727.             Matched("@open");
  1728.             do_open(player, arg1, argv);
  1729.             break;
  1730.           default:
  1731.         goto bad;
  1732.         }
  1733.         break;
  1734.       case 'p':
  1735.       case 'P':
  1736.         switch (command[2]) {
  1737.           case 'a':
  1738.           case 'A':
  1739.           switch (command[3]) {
  1740.           case 'r':
  1741.           case 'R':
  1742.         Matched("@parent");
  1743.         do_parent(player, arg1, arg2);
  1744.         break;
  1745.           case 's':
  1746.           case 'S':
  1747.         Matched("@password");
  1748.         do_password(player, arg1, arg2);
  1749.         break;
  1750.           default:
  1751.         goto bad;
  1752.           }
  1753.           break;
  1754. #ifdef WCREAT
  1755.           case 'C':
  1756.           case 'c':
  1757.         Matched("@pcreate");
  1758.         do_pcreate(player, arg1, arg2);
  1759.         break;
  1760. #endif
  1761.               case 'E':
  1762.               case 'e':
  1763.         if (gagged)
  1764.           break;
  1765.                 Matched("@pemit");
  1766.               if (!slashp)
  1767. #ifdef SILENT_PEMIT
  1768.           do_pemit(player, arg1, arg2, 1);
  1769. #else
  1770.           do_pemit(player, arg1, arg2, 0);
  1771. #endif                /* SILENT_PEMIT */
  1772.             else IfSwitch("noisy")
  1773.           do_pemit(player, arg1, arg2, 0);
  1774.             else IfSwitch("silent")
  1775.           do_pemit(player, arg1, arg2, 1);
  1776.             else IfSwitch("contents")
  1777.           do_remit(player, arg1, arg2);
  1778.             else
  1779.           goto bad;
  1780.                 break;
  1781.           case 'O':
  1782.           case 'o':
  1783.         switch (command[3]) {
  1784. #ifdef AT_DOING
  1785.         case 'l':
  1786.         case 'L':
  1787.           Matched("@poll");
  1788.           do_poll(player, argu);
  1789.           break;
  1790. #endif                /* AT_DOING */
  1791.         case 'o':
  1792.         case 'O':
  1793.           if (strcmp(command, "@poor"))
  1794.             goto bad;
  1795.           do_poor(player, arg1);
  1796.           break;
  1797.         case 'w':
  1798.         case 'W':
  1799.           Matched("@power");
  1800.           do_power(player, arg1, arg2);
  1801.           break;
  1802.         default:
  1803.           goto bad;
  1804.         }
  1805.         break;
  1806.           case 'S':
  1807.           case 's':
  1808.         Matched("@ps");
  1809.             if (!slashp)
  1810.           do_queue(player, arg1);
  1811.             else IfSwitch("all")
  1812.           do_queue(player, "all");
  1813.               else IfSwitch("summary")
  1814.           do_queue(player, "count");
  1815.             else
  1816.           goto bad;
  1817.         break;
  1818. #ifdef DESTROY
  1819.           case 'u':
  1820.           case 'U':
  1821.         Matched("@purge");
  1822.         do_purge(player);
  1823.         break;
  1824. #endif                /* DESTROY */
  1825.           default:
  1826.         goto bad;
  1827.           }
  1828.         break;
  1829. #ifdef QUOTA
  1830.       case 'q':
  1831.       case 'Q':
  1832.         Matched("@quota");
  1833.         if (!slashp)
  1834.           do_quota(player, arg1, "", 0);
  1835.         else IfSwitch("all")
  1836.           do_allquota(player, arg1);
  1837.         else IfSwitch("set")
  1838.           do_quota(player, arg1, arg2, 1);
  1839.         else
  1840.           goto bad;
  1841.         break;
  1842. #endif /* QUOTA */
  1843.           case 'r':
  1844.           case 'R':
  1845.         switch (command[2]) {
  1846.         case 'e':
  1847.         case 'E':
  1848.           if (gagged) break;
  1849.           switch (command[3]) {
  1850.           case 'a':
  1851.           case 'A':
  1852.         Matched("@readcache");
  1853.         do_readcache(player);
  1854.         break;
  1855.           case 'm':
  1856.           case 'M':
  1857.         Matched("@remit");
  1858.         do_remit(player, arg1, arg2);
  1859.         break;
  1860.           case 'j':
  1861.           case 'J':
  1862.         Matched("@rejectmotd");
  1863.         do_motd(player, 4, argu);
  1864.         break;
  1865.           default:
  1866.         goto bad;
  1867.           }
  1868.           break;
  1869. #ifdef ROYALTY_FLAG
  1870.         case 'w':
  1871.         case 'W':
  1872.           if (string_prefix("@rwall", command)) {
  1873.         do_wall(player, argu, 1, 1);
  1874.           } else if (string_prefix("@rwallpose", command)) {
  1875.         do_wall(player, argu, 1, 2);
  1876.           } else if (string_prefix("@rwallemit", command)) {
  1877.         do_wall(player, argu, 1, 3);
  1878.           } else
  1879.         goto bad;
  1880.           break;
  1881. #endif
  1882.         default:
  1883.           goto bad;
  1884.         }
  1885.         break;
  1886.       case 's':
  1887.       case 'S':
  1888.         /* set, shutdown, success */
  1889.         switch (command[2]) {
  1890.             case 'c':
  1891.           case 'C':
  1892.             if (gagged)
  1893.           break;
  1894.         Matched("@scan");
  1895.         if (!slashp)
  1896.           do_scan(player, argu, CHECK_INVENTORY | CHECK_NEIGHBORS | 
  1897.               CHECK_SELF | CHECK_HERE | CHECK_ZONE | CHECK_GLOBAL);
  1898.         else IfSwitch("room")
  1899.           do_scan(player, argu, CHECK_NEIGHBORS | CHECK_HERE);
  1900.         else IfSwitch("self")
  1901.           do_scan(player, argu, CHECK_INVENTORY | CHECK_SELF);
  1902.         else IfSwitch("zone")
  1903.           do_scan(player, argu, CHECK_ZONE);
  1904.         else IfSwitch("globals")
  1905.           do_scan(player, argu, CHECK_GLOBAL);
  1906.         else
  1907.           goto bad;
  1908.         break;
  1909.           case 'e':
  1910.           case 'E':
  1911.         /* patched to add 'search' command */
  1912.         switch (command[3]) {
  1913.           case 'a':
  1914.           case 'A':
  1915.             Matched("@search");
  1916.             do_search(player, arg1, vargs);
  1917.             break;
  1918.           case 'l':
  1919.           case 'L':
  1920.             Matched("@select");
  1921.             do_switch(player, arg1, vargs, cause, 1);
  1922.             break;
  1923.           case 't':
  1924.           case 'T':
  1925.             if (gagged)
  1926.               break;
  1927.             Matched("@set");
  1928.             do_set(player, arg1, arg2);
  1929.             break;
  1930.           default:
  1931.             goto bad;
  1932.         }
  1933.         break;
  1934.           case 'h':
  1935.           case 'H':
  1936.         if (strcmp(command, "@shutdown"))
  1937.           goto bad;
  1938.         do_shutdown(player);
  1939.         break;
  1940.           case 't':
  1941.           case 'T':
  1942.         Matched("@stats");
  1943. #ifdef DBSTATS_ENABLED
  1944.         if (!slashp)
  1945.           do_stats(player, arg1);
  1946.         else IfSwitch("database")
  1947.           do_dbstats(player);
  1948.         else
  1949.           goto bad;
  1950. #else
  1951.         do_stats(player, arg1);
  1952. #endif                /* DBSTATS_ENABLED */
  1953.         break;
  1954.           case 'w':
  1955.           case 'W':
  1956.         switch (command[3]) {
  1957.           case 'e':
  1958.           case 'E':
  1959.             Matched("@sweep");
  1960.             if (!slashp)
  1961.               do_sweep(player, arg1);
  1962.             else IfSwitch("connected")
  1963.               do_sweep(player, "connected");
  1964.             else IfSwitch("here")
  1965.               do_sweep(player, "here");
  1966.             else IfSwitch("inventory")
  1967.               do_sweep(player, "inventory");
  1968.             else IfSwitch("exits")
  1969.               do_sweep(player, "exits");
  1970.             else
  1971.               goto bad;
  1972.             break;
  1973.           case 'i':
  1974.           case 'I':
  1975.             if (gagged)
  1976.               break;
  1977.             Matched("@switch");
  1978.             if (!slashp)
  1979.               do_switch(player, arg1, vargs, cause, 0);
  1980.             else IfSwitch("first")
  1981.               do_switch(player, arg1, vargs, cause, 1);
  1982.             else IfSwitch("all")
  1983.               do_switch(player, arg1, vargs, cause, 0);
  1984.             else
  1985.               goto bad;
  1986.             break;
  1987.           default:
  1988.             goto bad;
  1989.         }
  1990.         break;
  1991. #ifdef QUOTA
  1992.           case 'q':
  1993.           case 'Q':
  1994.         Matched("@squota");
  1995.         do_quota(player, arg1, arg2, 1);
  1996.         break;
  1997. #endif /* QUOTA */
  1998.           default:
  1999.         goto bad;
  2000.         }
  2001.         break;
  2002.       case 't':
  2003.       case 'T':
  2004.         switch (command[2]) {
  2005.           case 'e':
  2006.           case 'E':
  2007.         if (gagged)
  2008.           break;
  2009.         Matched("@teleport");
  2010.         do_teleport(player, arg1, arg2);
  2011.         break;
  2012.           case 'r':
  2013.           case 'R':
  2014.         if (gagged)
  2015.           break;
  2016.         Matched("@trigger");
  2017.         do_trigger(player, arg1, argv);
  2018.         break;
  2019.           case 'O':
  2020.           case 'o':
  2021.         if (strcmp(command, "@toad"))
  2022.           goto bad;
  2023.         do_toad(player, arg1);
  2024.         break;
  2025.           default:
  2026.         goto bad;
  2027.         }
  2028.         break;
  2029.       case 'u':
  2030.       case 'U':
  2031.         switch (command[2]) {
  2032.         case 'l':
  2033.         case 'L':
  2034.           if (gagged) break;
  2035.           Matched("@ulock");
  2036.           do_lock(player, arg1, arg2, USELOCK);
  2037.           break;
  2038.         case 'n':
  2039.         case 'N':
  2040.           switch (command[4]) {
  2041.           case 'i':
  2042.           case 'I':
  2043.         if (gagged) break;
  2044.         Matched("@unlink");
  2045.         do_unlink(player, arg1);
  2046.         break;
  2047.           case 'o':
  2048.           case 'O':
  2049.         if (gagged) break;
  2050.         Matched("@unlock");
  2051.           if (!slashp)
  2052.             do_unlock(player, arg1, BASICLOCK);
  2053.           else IfSwitch("enter")
  2054.             do_unlock(player, arg1, ENTERLOCK);
  2055.           else IfSwitch("tport")
  2056.             do_unlock(player, arg1, ENTERLOCK);
  2057.           else IfSwitch("page")
  2058.             do_unlock(player, arg1, USELOCK);
  2059.           else IfSwitch("use")
  2060.             do_unlock(player, arg1, USELOCK);
  2061.           else 
  2062.             goto bad;
  2063.         break;
  2064.           default:
  2065.         goto bad;
  2066.           }
  2067.           break;
  2068.         case 'p':
  2069.         case 'P':
  2070.           Matched("@uptime");
  2071.           do_uptime(player);
  2072.           break;
  2073.         case 'u':
  2074.         case 'U':
  2075.           if (gagged) break;
  2076.           Matched("@uunlock");
  2077.           do_unlock(player, arg1, USELOCK);
  2078.           break;
  2079.         default:
  2080.           goto bad;
  2081.         }
  2082.         break;
  2083.           case 'v':
  2084.       case 'V':
  2085.         switch (command[4]) {
  2086.         case 'b':
  2087.         case 'B':
  2088.           Matched("@verb");
  2089.           do_verb(player, cause, arg1, argv);
  2090.           break;
  2091.         case 's':
  2092.         case 'S':
  2093.           Matched("@version");
  2094.           do_version(player);
  2095.           break;
  2096.         default:
  2097.           goto bad;
  2098.             }
  2099.         break;
  2100.       case 'w':
  2101.       case 'W':
  2102.         switch (command[2]) {
  2103.           case 'a':
  2104.           case 'A':
  2105.         if (string_prefix("@wait", command)) {
  2106.           do_wait(player, cause, arg1, arg);
  2107.         } else if (string_prefix("@wall", command)) {
  2108.             Matched("@wall");
  2109.             if (!slashp)
  2110.               do_wall(player, argu, 2, 1);
  2111.             else IfSwitch("wizard")
  2112.               do_wall(player, argu, 0, 1);
  2113.             else IfSwitch("royalty")
  2114.               do_wall(player, argu, 1, 1);
  2115.             else IfSwitch("emit")
  2116.               do_wall(player, argu, 2, 3);
  2117.             else IfSwitch("pose")
  2118.               do_wall(player, argu, 2, 2);
  2119.             else
  2120.               goto bad;
  2121.         } else if (string_prefix("@wallpose", command)) {
  2122.             do_wall(player, argu, 2, 2);
  2123.         } else if (string_prefix("@wallemit", command)) {
  2124.             do_wall(player, argu, 2, 3);
  2125.         } else
  2126.           goto bad;
  2127.         break;
  2128. #ifdef PLAYER_LOCATE
  2129.           case 'h':
  2130.           case 'H':
  2131.         if (gagged)
  2132.           break;
  2133.         Matched("@whereis");
  2134.         do_whereis(player, arg1);
  2135.         break;
  2136. #endif                /* PLAYER_LOCATE */
  2137.           case 'i':
  2138.           case 'I':
  2139.         if (string_prefix("@wipe", command)) {
  2140.           do_wipe(player, arg1);
  2141.         } else if(string_prefix("@wizwall", command)) {
  2142.           do_wall(player, argu, 0, 1);
  2143.         } else if(string_prefix("@wizmotd", command)) {
  2144.           do_motd(player, 2, argu);
  2145.         } else if(string_prefix("@wizpose", command)) {
  2146.           do_wall(player, argu, 0, 2);
  2147.         } else if(string_prefix("@wizemit", command)) {
  2148.           do_wall(player, argu, 0, 3);
  2149.         } else
  2150.           goto bad;
  2151.         break;
  2152.           default:
  2153.         goto bad;
  2154.         }
  2155.         break;
  2156.       case 'z':
  2157.       case 'Z':
  2158.         if (gagged) break;
  2159.         Matched("@zemit");
  2160.         do_zemit(player, arg1, arg2);
  2161.         break;
  2162.       default:
  2163.         goto bad;
  2164.     }
  2165.     break;
  2166.       case 'b':
  2167.       case 'B':
  2168.     Matched("brief");
  2169.     do_examine(player, arg1, 1);
  2170.     break;
  2171.       case 'd':
  2172.       case 'D':
  2173.     if (!Mobile(player))
  2174.       break;
  2175.     Matched("drop");
  2176.     do_drop(player, arg1);
  2177.     break;
  2178.       case 'e':
  2179.       case 'E':
  2180.     switch (command[1]) {
  2181.       case 'X':
  2182.       case 'x':
  2183.       case '\0':
  2184.         Matched("examine");
  2185.         if (!slashp)
  2186.           do_examine(player, arg1, 0);
  2187.         else IfSwitch("brief")
  2188.           do_examine(player, arg1, 1);
  2189.         else IfSwitch("debug")
  2190.           do_debug_examine(player, arg1);
  2191.         else
  2192.           goto bad;
  2193.         break;
  2194.       case 'N':
  2195.       case 'n':
  2196.         if(Typeof(player) == TYPE_EXIT || Typeof(player) == TYPE_ROOM)
  2197.           break;
  2198.         Matched("enter");
  2199.         do_enter(player, arg1, 0);
  2200.         break;
  2201. #ifdef EVENTS
  2202.       case 'v':
  2203.       case 'V':
  2204.         Matched("events");
  2205.         do_new_spitfile(player, buff3, EVENTINDX, EVENT_FILE);
  2206.         break;
  2207. #endif
  2208.       default:
  2209.         goto bad;
  2210.     }
  2211.     break;
  2212.       case 'g':
  2213.       case 'G':
  2214.     /* get, give, go, or gripe */
  2215.     switch (command[1]) {
  2216.       case 'e':
  2217.       case 'E':
  2218.         if(gagged || !Mobile(player))
  2219.           break;
  2220.         Matched("get");
  2221.         do_get(player, arg1);
  2222.         break;
  2223.       case 'i':
  2224.       case 'I':
  2225.         if (gagged)
  2226.           break;
  2227.         Matched("give");
  2228.         do_give(player, arg1, arg2);
  2229.         break;
  2230.       case 'o':
  2231.       case 'O':
  2232.         if(Typeof(player) == TYPE_EXIT || Typeof(player) == TYPE_ROOM)
  2233.           break;
  2234.         Matched("goto");
  2235.         move_wrapper(player, arg1);
  2236.         break;
  2237.       default:
  2238.         goto bad;
  2239.     }
  2240.     break;
  2241.       case 'h':
  2242.       case 'H':
  2243.     Matched("help");
  2244.     do_new_spitfile(player, buff3, HELPINDX, HELPTEXT);
  2245.     break;
  2246.       case 'i':
  2247.       case 'I':
  2248.     Matched("inventory");
  2249.     do_inventory(player);
  2250.     break;
  2251.       case 'k':
  2252.       case 'K':
  2253.     if (gagged)
  2254.       break;
  2255.     Matched("kill");
  2256.     do_kill(player, arg1, atol(arg2), 0);
  2257.     break;
  2258.       case 'l':
  2259.       case 'L':
  2260.     switch (command[1]) {
  2261.       case '\0':        /* patch allow 'l' command to do a look */
  2262.           do_look_at(player, arg1, 0);
  2263.         break;
  2264.       case 'o':
  2265.       case 'O':
  2266.         Matched("look");
  2267.         if (!slashp)
  2268.           do_look_at(player, arg1, 0);
  2269.         else IfSwitch("outside")
  2270.           do_look_at(player, arg1, 1);
  2271.         else
  2272.           goto bad;
  2273.         break;
  2274.       case 'E':
  2275.       case 'e':
  2276.         if(Typeof(player) == TYPE_ROOM || Typeof(player) == TYPE_EXIT)
  2277.           break;
  2278.         Matched("leave");
  2279.         do_leave(player);
  2280.         break;
  2281.       default:
  2282.         goto bad;
  2283.     }
  2284.     break;
  2285.       case 'm':
  2286.       case 'M':
  2287.     if (!Mobile(player))
  2288.       break;
  2289.     Matched("move");
  2290.     move_wrapper(player, arg1);
  2291.     break;
  2292.       case 'n':
  2293.       case 'N':
  2294.     /* news */
  2295.     if (strcasecmp(command, "news"))
  2296.       goto bad;
  2297.     do_new_spitfile(player, buff3, NEWSINDX, NEWS_FILE);
  2298.     break;
  2299.       case 'p':
  2300.       case 'P':
  2301.     if (gagged)
  2302.       break;
  2303.     Matched("page");
  2304.     if (index(buff3, '=') == NULL)
  2305.       do_page(player, argu, NULL);
  2306.     else
  2307.       do_page(player, arg1, arg2);
  2308.     break;
  2309.       case 'r':
  2310.       case 'R':
  2311.     switch (command[1]) {
  2312. #ifdef ROBBERS
  2313.     case 'o':
  2314.     case 'O':
  2315.       Matched("rob");
  2316.       do_rob(player, arg1);
  2317.       break;
  2318. #endif                /* ROBBERS */
  2319. #ifdef ALLOW_RPAGE
  2320.     case 'p':
  2321.     case 'P':
  2322.       Matched("rpage");
  2323.       if (!slashp)
  2324.         do_rpage(player, arg1, arg2);
  2325.       else IfSwitch("list")
  2326.         do_rpage_list(player);
  2327.       else IfSwitch("add")
  2328.         do_rpage_add(player, arg1, arg2);
  2329.       else IfSwitch("delete")
  2330.         do_rpage_delete(player, arg1, arg2);
  2331.       else
  2332.         goto bad;
  2333.       break;
  2334. #endif                /* ALLOW_RPAGE */
  2335.     default:
  2336.       Matched("read");    /* undocumented alias for look at */
  2337.       do_look_at(player, arg1, 0);
  2338.       break;
  2339.     }
  2340.     break;
  2341.       case 's':
  2342.       case 'S':
  2343.     /* say, "score" */
  2344.     switch (command[1]) {
  2345.       case 'a':
  2346.       case 'A':
  2347.         if (gagged)
  2348.           break;
  2349.         Matched("say");
  2350.         do_say(player, argu);
  2351.         break;
  2352.       case 'c':
  2353.       case 'C':
  2354.         Matched("score");
  2355.         do_score(player);
  2356.         break;
  2357.       case 'l':
  2358.       case 'L':
  2359.         Matched("slay");
  2360.         do_kill(player, arg1, 0, 1);
  2361.         break;
  2362.       default:
  2363.         goto bad;
  2364.     }
  2365.     break;
  2366.       case 't':
  2367.       case 'T':
  2368.     switch (command[1]) {
  2369.       case 'a':
  2370.       case 'A':
  2371.         if(gagged || !Mobile(player))
  2372.           break;
  2373.         Matched("take");
  2374.         do_get(player, arg1);
  2375.         break;
  2376.       case 'h':
  2377.       case 'H':
  2378.         if (gagged)
  2379.           break;
  2380.         Matched("think");
  2381.         do_think(player, argu);
  2382.         break;
  2383.       default:
  2384.         goto bad;
  2385.     }
  2386.     break;
  2387.       case 'w':
  2388.       case 'W':
  2389.     if (gagged)
  2390.       break;
  2391.     Matched("whisper");
  2392.     do_whisper(player, arg1, arg2);
  2393.     break;
  2394.       case 'u':
  2395.       case 'U':
  2396.     if (gagged) break;
  2397.     Matched("use");
  2398.     do_use(player, arg1);
  2399.     break;
  2400.       default:
  2401.       bad:
  2402.  
  2403.     /* now we do function evaluation on the command line, since
  2404.      * from now on we're going to be passing the entire thing
  2405.      * on to whatever handler we're using.
  2406.      */
  2407.  
  2408.     cptr = exec(player, cause, EV_EVAL | EV_FCHECK | EV_STRIP, unp);
  2409.     a = 0;
  2410.     if (!gagged && Mobile(player)) {
  2411.  
  2412.       /* if the "player" is an exit or room, no need to do these checks */
  2413.  
  2414.       /* try matching enter aliases */
  2415.       if (Location(player) != NOTHING &&
  2416.           (i = alias_list_check(db[Location(player)].contents, 
  2417.                     cptr, "EALIAS")) != -1) {
  2418.  
  2419.         sprintf(temp, "#%d", i);
  2420.         do_enter(player, temp, 1);
  2421.         goto done;
  2422.       }
  2423.  
  2424.       /* if that didn't work, try matching leave aliases */
  2425.       if ((Typeof(Location(player)) != TYPE_ROOM) &&
  2426.           (loc_alias_check(Location(player), cptr, "LALIAS"))) {
  2427.         do_leave(player);
  2428.         goto done;
  2429.       }
  2430.  
  2431.       /* try matching user defined functions before chopping */
  2432.  
  2433.       /* try objects in the player's location, the location itself,
  2434.        * and objects in the player's inventory.
  2435.        */
  2436.       if (Location(player) != NOTHING) {
  2437.         a += list_match(Contents(Location(player)));
  2438.         if (Location(player) != player)
  2439.           a += cmd_match(Location(player));
  2440.       }
  2441.       if (Location(player) != player)
  2442.         a += list_match(Contents(player));
  2443.  
  2444.       /* now do check on zones */
  2445.       if ((!a) && (Zone(Location(player)) != NOTHING)) {
  2446. #ifdef DO_GLOBALS
  2447.         if (Typeof(Zone(Location(player))) == TYPE_ROOM) {
  2448.  
  2449.           /* zone of player's location is a parent room */
  2450.  
  2451.           if (Location(player) != Zone(player)) {
  2452.  
  2453.         /* check parent room exits */
  2454.         if (remote_exit(Zone(Location(player)), cptr)) {
  2455.           if (!Mobile(player))
  2456.             goto done;
  2457.           else {
  2458.             do_move(player, cptr, 2);
  2459.             goto done;
  2460.           }
  2461.         } else
  2462.           /* check commands in the parent room if no exits
  2463.            * can match more than one $command in parent room
  2464.            */
  2465.           a += list_match(Contents(Zone(Location(player))));
  2466.           }            /* end of parent room check */
  2467.         } else
  2468. #endif
  2469.           /* try matching commands on area zone object if GLOBALS
  2470.            * aren't in use or zone object isn't a room
  2471.            */
  2472.           if ((!a) && (Zone(Location(player)) != NOTHING))
  2473.         a += cmd_match(Zone(Location(player)));
  2474.       } /* end of matching on zone of player's location */
  2475.  
  2476.       /* if nothing matched with parent room/zone object, try
  2477.        * matching zone commands on the player's personal zone
  2478.        */
  2479.       if ((!a) && (Zone(player) != NOTHING) &&
  2480.           (Zone(Location(player)) != Zone(player))) {
  2481.         a += cmd_match(Zone(player));
  2482.       }  /* end of zone stuff */
  2483.  
  2484. #ifdef DO_GLOBALS
  2485.       /* check global exits only if no other commands are matched */
  2486.       if ((!a) && (Location(player) != MASTER_ROOM)) {
  2487.         if (global_exit(player, cptr)) {
  2488.           if (!Mobile(player))
  2489.         goto done;
  2490.           else {
  2491.         do_move(player, cptr, 1);
  2492.         goto done;
  2493.           }
  2494.         } else
  2495.           /* global user-defined commands checked if all else fails.
  2496.            * May match more than one command in the master room.
  2497.            */
  2498.           a += list_match(Contents(MASTER_ROOM));
  2499.       }            /* end of master room check */
  2500. #endif
  2501.     }                /* end of special checks */
  2502.     if(!a) {
  2503.       notify(player, "Huh?  (Type \"help\" for help.)");
  2504.       if (options.log_huhs)
  2505.         do_log(LT_HUH, player, 0, "%s", unp);
  2506.     }
  2507.     break;
  2508.       }
  2509.   }
  2510.  
  2511.   /* command has been executed. Free up memory. */
  2512.  
  2513. done:
  2514.  
  2515.   if (cptr)
  2516.     free(cptr);
  2517.  
  2518.   if (buf1) {
  2519.     free(buf1);
  2520. #ifdef MEM_CHECK
  2521.     del_check("exec.buff");
  2522. #endif
  2523.   }
  2524.  
  2525.   if (saveptr) {        /* arg2 */
  2526.     free(saveptr);
  2527. #ifdef MEM_CHECK
  2528.     del_check("exec.buff");
  2529. #endif
  2530.   }
  2531.  
  2532.   for (a = 0; a < MAX_ARG; a++) {       /* argv */
  2533.     if (fargs[a]) {
  2534.       free((char *) fargs[a]);
  2535. #ifdef MEM_CHECK
  2536.       del_check("exec.buff");
  2537. #endif
  2538.       fargs[a] = NULL;
  2539.     }
  2540.   }
  2541.  
  2542.   /* Hmm. This is a possible fix for the %0 bug. (T'nor@SC's suggestion)
  2543.       for (a = 0; a < 10; a++)
  2544.         wptr[a] = NULL;
  2545.      The problem with this is that it screws up multiple statements
  2546.      associated with a single group of stack values, i.e:
  2547.      @va object=$test *:@emit %0; say %0
  2548.    */
  2549. }
  2550.  
  2551.  
  2552. /* now undef everything that needs to be */
  2553. #undef Matched
  2554. #undef arg1
  2555. #undef arg2
  2556. #undef argu
  2557. #undef argv
  2558. #undef vargs
  2559. #undef list_match
  2560. #undef cmd_match
  2561.  
  2562. int check_alias(command, list)
  2563.      const char *command;
  2564.      const char *list;
  2565. {
  2566.   /* check if a string matches part of a semi-colon separated list */
  2567.   const char *p;
  2568.   while (*list) {
  2569.     for (p = command; (*p && DOWNCASE(*p) == DOWNCASE(*list)
  2570.                && *list != EXIT_DELIMITER);
  2571.      p++, list++)
  2572.     ;
  2573.   if (*p == '\0') {
  2574.     while (isspace(*list))
  2575.       list++;
  2576.     if (*list == '\0' || *list == EXIT_DELIMITER)
  2577.       return 1;            /* word matched */
  2578.   }
  2579.   /* didn't match. check next word in list */
  2580.   while (*list && *list++ != EXIT_DELIMITER)
  2581.     ;
  2582.   while (isspace(*list))
  2583.     list++;
  2584.   }
  2585.   /* reached the end of the list without matching anything */
  2586.   return 0;
  2587. }
  2588.  
  2589. /* match a list of things */
  2590. int list_check(thing, player, type, end, str, just_match)
  2591.     dbref thing, player;
  2592.     char type, end;
  2593.     char *str;
  2594.     int just_match;
  2595. {
  2596.   int match = 0;
  2597.  
  2598.   while (thing != NOTHING) {
  2599.     if (atr_comm_match(thing, player, type, end, str, just_match))
  2600.       match = 1;
  2601.     thing = db[thing].next;
  2602.   }
  2603.   return (match);
  2604. }
  2605.  
  2606. int alias_list_check(thing, command, type)
  2607.   dbref thing;
  2608.   const char *command;
  2609.   char *type;
  2610. {
  2611.   ATTR *a;
  2612.   char alias[BUFFER_LEN];
  2613.  
  2614.   while (thing != NOTHING) {
  2615.     a = atr_get_noparent(thing, type);
  2616.     if (a) {
  2617.       strcpy(alias, uncompress(a -> value));
  2618.       if (check_alias(command, alias) != 0)
  2619.     return thing;        /* matched an alias */
  2620.     }
  2621.     thing = db[thing].next;
  2622.   }
  2623.   return -1;
  2624. }
  2625.  
  2626. int loc_alias_check(loc, command, type)
  2627.   dbref loc;
  2628.   const char *command;
  2629.   char *type;
  2630. {
  2631.   ATTR *a;
  2632.   char alias[BUFFER_LEN];
  2633.   a = atr_get_noparent(loc, type);
  2634.   if (a) {
  2635.     strcpy(alias, uncompress(a -> value));
  2636.     return (check_alias(command, alias));
  2637.   } else
  2638.     return 0;
  2639. }
  2640.  
  2641. int Hearer(thing)
  2642.     dbref thing;
  2643. {
  2644.   ALIST *ptr;
  2645.  
  2646.   if (IS(thing, TYPE_PLAYER, PLAYER_CONNECT) || Puppet(thing))
  2647.     return (1);
  2648.   for (ptr = db[thing].list; ptr; ptr = AL_NEXT(ptr)) {
  2649.     if(!AL_BAD(ptr) && !strcmp(AL_NAME(ptr), "LISTEN"))
  2650.       return 1;
  2651.   }
  2652.   return (0);
  2653. }
  2654.  
  2655. int Commer(thing)
  2656.     dbref thing;
  2657. {
  2658.   ALIST *ptr;
  2659.  
  2660.   for (ptr = db[thing].list; ptr; ptr = AL_NEXT(ptr)) {
  2661.     if(!AL_BAD(ptr)) {
  2662.       if(*AL_STR(ptr) == '$')
  2663.         return (1);
  2664.     }
  2665.   }
  2666.   return (0);
  2667. }
  2668.  
  2669. int Listener(thing)
  2670.      dbref thing;
  2671. {
  2672.   ALIST *ptr;
  2673.   if (IS(thing, TYPE_THING, THING_LISTEN))
  2674.     return (1);
  2675.   for (ptr = db[thing].list; ptr; ptr = AL_NEXT(ptr)) {
  2676.     if(!AL_BAD(ptr)) {
  2677.       if(*AL_STR(ptr) == '^')
  2678.         return (1);
  2679.     }
  2680.   }
  2681.   return (0);
  2682. }
  2683.  
  2684. void do_poor(player, arg1)
  2685.      dbref player;
  2686.      char *arg1;
  2687. {
  2688.   int amt = atoi(arg1);
  2689.   dbref a;
  2690.   if (!God(player)) {
  2691.     notify(player, "Only God can cause financial ruin.");
  2692.     return;
  2693.   }
  2694.   for (a = 0; a < db_top; a++)
  2695.     if (Typeof(a) == TYPE_PLAYER)
  2696.       s_Pennies(a, amt);
  2697.   notify(player,
  2698.      tprintf("The money supply of all players has been reset to %d %s.",
  2699.          amt, MONIES));
  2700.   do_log(LT_WIZ, player, NOTHING, 
  2701.      "** POOR done ** Money supply reset to %d %s.",
  2702.      amt, MONIES);
  2703.   fflush(wizlog_fp);
  2704. }
  2705.  
  2706. void do_version(player)
  2707.     dbref player;
  2708. {
  2709.   char buff[BUFFER_LEN];
  2710.  
  2711.   notify(player, tprintf("You are connected to %s", MUDNAME));
  2712.  
  2713.   strcpy(buff, ctime(&start_time));
  2714.   buff[strlen(buff) - 1] = '\0';     /* eat the newline */
  2715.   notify(player, tprintf("Last restarted: %s", buff));
  2716.  
  2717.   notify(player, tprintf("%s", VERSION));
  2718.   notify(player, tprintf("Build date: %s %s", __TIME__, __DATE__));
  2719. }
  2720.  
  2721. /* Bind occurences of '##' in "action" to "arg", then run "action" */
  2722.  
  2723. void bind_and_queue(player, cause, action, arg)
  2724.      dbref player;
  2725.      dbref cause;
  2726.      char *action;
  2727.      char *arg;
  2728. {
  2729.   char *repl, *command;
  2730.  
  2731.   repl = replace_string("##", arg, action);
  2732.   command = strip_braces(repl);
  2733.  
  2734.   if (repl)
  2735.     free(repl);
  2736. #ifdef MEM_CHECK
  2737.   del_check("replace_string.buff");
  2738. #endif
  2739.  
  2740.   parse_que(player, command, cause);
  2741.  
  2742.   if (command)
  2743.     free(command);
  2744. #ifdef MEM_CHECK
  2745.   del_check("strip_braces.buff");
  2746. #endif
  2747. }
  2748.  
  2749. void do_scan(player, command, flag)
  2750.      dbref player;
  2751.      char *command;
  2752.      int flag;
  2753. {
  2754.   /* scan for possible matches of user-def'ed commands */
  2755.  
  2756. #define ScanFind(p,x)  \
  2757.   (Can_Examine(p,x) && \
  2758.       ((num = atr_comm_match(x, p, '$', ':', command, 1)) != 0))
  2759.  
  2760.  
  2761.   dbref thing;
  2762.   int num;
  2763.  
  2764.   if (!GoodObject(Location(player))) {
  2765.     notify(player, "Sorry, you are in an invalid location.");
  2766.     return;
  2767.   }
  2768.   if (!command || !*command) {
  2769.     notify(player, "What command do you want to scan for?");
  2770.     return;
  2771.   }
  2772.  
  2773.   if (flag & CHECK_NEIGHBORS) {
  2774.     notify(player, "Matches on contents of this room:");
  2775.     DOLIST(thing, db[Location(player)].contents) {
  2776.       if (ScanFind(player, thing))
  2777.     notify(player, 
  2778.            tprintf("%s  [%d]", unparse_object(player, thing), num));
  2779.     }
  2780.   }
  2781.  
  2782.   if (flag & CHECK_HERE) {
  2783.     if (ScanFind(player, Location(player)))
  2784.       notify(player, tprintf("Matched here: %s  [%d]", 
  2785.                  unparse_object(player, Location(player)), num));
  2786.   }
  2787.  
  2788.   if (flag & CHECK_INVENTORY) {
  2789.     notify(player, "Matches on carried objects:");
  2790.     DOLIST(thing, db[player].contents) {
  2791.       if (ScanFind(player, thing))
  2792.     notify(player, tprintf("%s  [%d]", 
  2793.                    unparse_object(player, thing), num));
  2794.     }
  2795.   }
  2796.  
  2797.   if (flag & CHECK_SELF) {
  2798.     if (ScanFind(player, player))
  2799.       notify(player, tprintf("Matched self: %s  [%d]", 
  2800.                  unparse_object(player, player), num));
  2801.   }
  2802.  
  2803.   if (flag & CHECK_ZONE) {
  2804.     /* zone checks */
  2805.     if (Zone(Location(player)) != NOTHING) {
  2806.       if (Typeof(Zone(Location(player))) == TYPE_ROOM) {
  2807.     /* zone of player's location is a parent room */
  2808.     if (Location(player) != Zone(player)) {
  2809.       notify(player, "Matches on parent room of location:");
  2810.       DOLIST(thing, db[Zone(Location(player))].contents) {
  2811.         if (ScanFind(player, thing))
  2812.           notify(player, tprintf("%s  [%d]", 
  2813.                      unparse_object(player, thing), num));
  2814.       }
  2815.     }
  2816.       } else {
  2817.     /* regular zone object */
  2818.     if (ScanFind(player, Zone(Location(player))))
  2819.       notify(player, 
  2820.          tprintf("Matched zone of location: %s  [%d]",
  2821.              unparse_object(player, Zone(Location(player))), num));
  2822.       }
  2823.     }
  2824.     if ((Zone(player) != NOTHING) && 
  2825.     (Zone(player) != Zone(Location(player)))) {
  2826.       /* check the player's personal zone */
  2827.       if (ScanFind(player, Zone(player)))
  2828.     notify(player, tprintf("Matched personal zone: %s  [%d]",
  2829.                    unparse_object(player, Zone(player)), num));
  2830.     }
  2831.   }
  2832.  
  2833. #ifdef DO_GLOBALS
  2834.   if ((flag & CHECK_GLOBAL) && 
  2835.       (Location(player) != MASTER_ROOM) &&
  2836.       (Zone(Location(player)) != MASTER_ROOM) && 
  2837.       (Zone(player) != MASTER_ROOM)) {
  2838.     /* try Master Room stuff */
  2839.     notify(player, "Matches on objects in the Master Room:");
  2840.     DOLIST(thing, db[MASTER_ROOM].contents) {
  2841.       if (ScanFind(player, thing))
  2842.     notify(player, tprintf("%s  [%d]", 
  2843.                    unparse_object(player, thing), num));
  2844.     }
  2845.   }
  2846. #endif                /* DO_GLOBALS */
  2847. }
  2848.  
  2849. void do_dolist(player, list, command, cause, flag)
  2850.     dbref player, cause;
  2851.     char *list, *command;
  2852.     int flag;            /* 0 for @dolist, 1 for @map */
  2853. {
  2854.   char *curr, *objstring;
  2855.   char outbuf[BUFFER_LEN];
  2856.   char *ptr, *ebuf;
  2857.  
  2858.   if (!list || !*list) {
  2859.     notify(player, "What do you want to do with the list?");
  2860.     return;
  2861.   }
  2862.  
  2863.   strcpy(outbuf, "");
  2864.  
  2865.   curr = list;
  2866.   while (curr && *curr) {
  2867.     while (*curr == ' ')
  2868.       curr++;
  2869.     if (*curr) {
  2870.       objstring = parse_to(&curr, ' ', EV_STRIP);
  2871.       if (!flag) {
  2872.     /* @dolist, queue command */
  2873.     bind_and_queue(player, cause, command, objstring);
  2874.       } else {
  2875.       /* it's @map, add to the output list */
  2876.     ebuf = replace_string("##", objstring, command);
  2877.     ptr = exec(player, cause, EV_STRIP | EV_FCHECK, ebuf);
  2878.     free(ebuf);
  2879. #ifdef MEM_CHECK
  2880.     del_check("replace_string.buff");
  2881. #endif
  2882.     if (!*outbuf)
  2883.       strcpy(outbuf, ptr);
  2884.     else if (strlen(outbuf) + strlen(ptr) < BUFFER_LEN)
  2885.       sprintf(outbuf, "%s %s", outbuf, ptr);
  2886.     free(ptr);
  2887. #ifdef MEM_CHECK
  2888.     del_check("exec.buff");
  2889. #endif
  2890.       }
  2891.     }
  2892.   }
  2893.  
  2894.   if (flag) {
  2895.     /* if we're doing a @map, copy the list to an attribute */
  2896.     atr_add(player, "MAPLIST", outbuf, GOD, NOTHING);
  2897.     notify(player, "Function mapped onto list.");
  2898.   }
  2899. }
  2900.  
  2901. void do_uptime(player)
  2902.      dbref player;
  2903. {
  2904.   FILE *fp;
  2905.   char c;
  2906.   char tbuf1[100];
  2907.   int i;
  2908.   int pid, psize;
  2909.   int sec, min;
  2910. #ifdef HAS_RUSAGE
  2911.   struct rusage usage;
  2912. #endif                /* HAS_RUSAGE */
  2913.  
  2914.   /* calculate time until next dump */
  2915.   min = options.dump_counter / 60;
  2916.   sec = options.dump_counter % 60;
  2917.  
  2918.   if (!Wizard(player)) {
  2919.     notify(player, 
  2920.        tprintf("Time until next database save: %d minutes %d seconds.",
  2921.            min, sec));
  2922.     return;
  2923.   }
  2924.  
  2925.   fp = popen("uptime", "r");
  2926.  
  2927.   /* just in case the system is screwy */
  2928.   if (fp == NULL) {
  2929.     notify(player, "Error -- cannot execute uptime.");
  2930.     fprintf(stderr, "** ERROR ** popen for @uptime returned NULL.");
  2931.     return;
  2932.   }
  2933.  
  2934.   /* print system uptime */
  2935.   for (i = 0; (c = getc(fp)) != '\n'; i++)
  2936.     tbuf1[i] = c;
  2937.   tbuf1[i] = '\0';
  2938.   pclose(fp);
  2939.  
  2940.   notify(player, tbuf1);
  2941.  
  2942.   /* do process stats */
  2943.  
  2944.   pid = getpid();
  2945.   psize = getpagesize();
  2946.   notify(player, tprintf("\nProcess ID:  %10d        %10d bytes per page",
  2947.              pid, psize));
  2948.  
  2949. #ifdef HAS_RUSAGE
  2950.   getrusage(RUSAGE_SELF, &usage);
  2951.   notify(player, tprintf("Time used:   %10d user   %10d sys",
  2952.              usage.ru_utime.tv_sec, usage.ru_stime.tv_sec));
  2953.   notify(player, tprintf("Max res mem: %10d pages  %10d bytes", 
  2954.              usage.ru_maxrss, (usage.ru_maxrss * psize)));
  2955.   notify(player, tprintf("Integral mem:%10d shared %10d private %10d stack",
  2956.              usage.ru_ixrss, usage.ru_idrss, usage.ru_isrss));
  2957.   notify(player, tprintf("Page faults: %10d hard   %10d soft    %10d swapouts",
  2958.              usage.ru_majflt, usage.ru_minflt, usage.ru_nswap));
  2959.   notify(player, tprintf("Disk I/O:    %10d reads  %10d writes",
  2960.              usage.ru_inblock, usage.ru_oublock));
  2961.   notify(player, tprintf("Network I/O: %10d in     %10d out",
  2962.              usage.ru_msgrcv, usage.ru_msgsnd));
  2963.   notify(player, tprintf("Context swi: %10d vol    %10d forced",
  2964.              usage.ru_nvcsw, usage.ru_nivcsw));
  2965.   notify(player, tprintf("Signals:     %10d", usage.ru_nsignals));
  2966. #endif                /* HAS_RUSAGE */
  2967.  
  2968.   notify(player, tprintf("The head of the object free list is #%d.",
  2969.              first_free));
  2970.   notify(player, 
  2971.      tprintf("Time until next database save: %d minutes %d seconds.",
  2972.          min, sec));
  2973. }
  2974.  
  2975. void do_config(player, type)
  2976.      dbref player;
  2977.      int type;
  2978. {
  2979.   if (type == 2) {
  2980.     notify(player, "Building costs:");
  2981.     notify(player, tprintf("  Object creation....%d", OBJECT_COST));
  2982.     notify(player, tprintf("  Room creation......%d", ROOM_COST));
  2983.     notify(player, tprintf("  Exit creation......%d", EXIT_COST));
  2984.     notify(player, tprintf("  Linking............%d", LINK_COST));
  2985.     notify(player, tprintf("  Queue deposit......%d", QUEUE_COST));
  2986.     notify(player, tprintf("  Quota per object...%d", QUOTA_COST));
  2987.     notify(player, "Command costs:");
  2988.     notify(player, tprintf("  page...............%d", PAGE_COST));
  2989.     notify(player, tprintf("  @find..............%d", FIND_COST));
  2990.     notify(player, tprintf("  kill base cost.....%d", KILL_BASE_COST));
  2991.     notify(player, tprintf("  kill minimum cost..%d", KILL_MIN_COST));
  2992.     notify(player, tprintf("  kill insurance.....%d", KILL_BONUS));
  2993.     return;
  2994.   }
  2995.  
  2996.   if (type == 1) {
  2997.     notify(player, "Global parameters:");
  2998.     notify(player, tprintf("  Logins............%s",
  2999.                (options.login_allow) ? "enabled" : "disabled"));
  3000.     notify(player, tprintf("  Daytime...........%s",
  3001.                (options.daytime) ? "enabled" : "disabled"));
  3002.     notify(player, tprintf("  Log commands......%s",
  3003.                (options.log_commands) ? "enabled" : "disabled"));
  3004.     notify(player, tprintf("  Log huhs..........%s",
  3005.                (options.log_huhs) ? "enabled" : "disabled"));
  3006.     notify(player, tprintf("  Log forces........%s",
  3007.                (options.log_forces) ? "enabled" : "disabled"));
  3008.     notify(player, tprintf("  Log wizwalls......%s",
  3009.                (options.log_walls) ? "enabled" : "disabled"));
  3010.     return;
  3011.   }
  3012.  
  3013. #ifdef RESTRICTED_BUILDING
  3014. #ifdef FREE_OBJECTS
  3015.   notify(player, "Players without a BUILDER bit can only create objects.");
  3016. #else
  3017.   notify(player, "Players without a BUILDER bit cannot build anything.");
  3018. #endif
  3019. #else
  3020.   notify(player, "Players do not need BUILDER bits to build.");
  3021. #endif
  3022.  
  3023. #ifdef QUOTA
  3024.   notify(player, "Quota restrictions are in effect.");
  3025. #else
  3026.   notify(player, "There are no quota restrictions.");
  3027. #endif                /* QUOTA */
  3028.  
  3029. #ifdef BUILDING_LIMIT
  3030.   notify(player, tprintf("There is a limit of %d objects.", DBTOP_MAX));
  3031. #else
  3032.   notify(player, "There is no maximum database size.");
  3033. #endif                /* BUILDING_LIMIT */
  3034.  
  3035. #ifdef USE_MAILER
  3036.   notify(player, "The built-in MUSH mailing system is being used.");
  3037. #else
  3038.   notify(player, "The built-in MUSH mailing system is not being used.");
  3039. #endif
  3040.  
  3041. #ifdef CONCENTRATOR
  3042.   notify(player, "Concentrator is enabling large numbers of connections.");
  3043. #else
  3044.   notify(player, "Concentrator is not enabled.");
  3045. #endif
  3046.  
  3047. #if (CHAT_SYSTEM >= 2)
  3048.   notify(player, "The chat system is enabled.");
  3049. #else
  3050.   notify(player, "The chat system is disabled.");
  3051. #endif
  3052.  
  3053. #ifdef LOCKOUT
  3054.   notify(player, "Site lockout is enabled.");
  3055. #else
  3056.   notify(player, "Site lockout is not enabled.");
  3057. #endif
  3058.  
  3059. #ifdef WCREAT
  3060.   notify(player, "Player registration is in effect.");
  3061. #else
  3062.   notify(player, "Player registration is not in effect.");
  3063. #endif
  3064.  
  3065. #ifdef FLAGS_ON_EXAMINE
  3066.   notify(player, "Examine shows the expanded flag list.");
  3067. #else
  3068.   notify(player, "Examine does not show the expanded flag list.");
  3069. #endif
  3070.  
  3071. #ifdef EX_PUBLIC_ATTRIBS
  3072.   notify(player, "Examine shows public attributes.");
  3073. #else
  3074.   notify(player, "Examine does not show public attributes.");
  3075. #endif
  3076.  
  3077. #ifdef TINY_ATTRS
  3078.   notify(player, "Attributes are printed in TinyMUSH format.");
  3079. #else
  3080.   notify(player, "Attributes are printed in expanded format.");
  3081. #endif
  3082.  
  3083. #ifdef FULL_INVIS
  3084.   notify(player, "Dark players/objects show up as Someone/Something.");
  3085. #else
  3086.   notify(player, "Dark players/objects are not totally anonymous.");
  3087. #endif
  3088.  
  3089. #ifdef PARANOID_NOSPOOF
  3090.   notify(player, "Nospoof notification shows name and object number.");
  3091. #else
  3092.   notify(player, "Nospoof notification shows the name of the object only.");
  3093. #endif
  3094.  
  3095. #ifdef PLAYER_LOCATE
  3096.   notify(player, "The location of players not set UNFINDABLE can be found.");
  3097. #else
  3098.   notify(player, "The location of players cannot be found.");
  3099. #endif
  3100.  
  3101. #ifdef PLAYER_LISTEN
  3102.   notify(player, "Players can @listen.");
  3103. #else
  3104.   notify(player, "Players cannot @listen.");
  3105. #endif
  3106.  
  3107. #ifdef FLOATING_POINTS
  3108.   notify(player, "Floating point functions are enabled.");
  3109. #else
  3110.   notify(player, "Floating point functions are not enabled.");
  3111. #endif
  3112.  
  3113. #ifdef AT_DOING
  3114.   notify(player, "Doing polls are enabled.");
  3115. #else
  3116.   notify(player, "Doing polls are not enabled.");
  3117. #endif
  3118.  
  3119. #ifdef GLOBAL_CONNECTS
  3120. #ifdef DO_GLOBALS
  3121.   notify(player, "Zone/global aconnects and adisconnects are enabled.");
  3122. #else
  3123.   notify(player, "Zone aconnects and adisconnects are enabled.");
  3124. #endif
  3125. #else
  3126.   notify(player, "Zone/global aconnects and disconnects are disabled.");
  3127. #endif
  3128.  
  3129. #ifdef ROYALTY_FLAG
  3130.   notify(player, "The ROYALTY flag is enabled.");
  3131. #else
  3132.   notify(player, "The ROYALTY flag is disabled.");
  3133. #endif
  3134.  
  3135. #ifdef INHERIT_FLAG
  3136.   notify(player, "The INHERIT flag is enabled.");
  3137. #else
  3138.   notify(player, "The INHERIT flag is disabled.");
  3139. #endif
  3140.  
  3141. #ifdef NO_FORK
  3142.   notify(player, "Forking is disabled. Game will freeze during dumps.");
  3143. #else
  3144.   notify(player, "There should be no slowdown due to database saves.");
  3145. #endif
  3146.  
  3147. notify(player, tprintf("The database is being saved every %d minutes.",
  3148.        (int) DUMP_INTERVAL / 60));
  3149.  
  3150. #ifdef RWHO_SEND
  3151.   notify(player, tprintf("The RWHO server is %s", RWHOSERV));
  3152. #ifdef FULL_WHO
  3153.     notify(player, "The MUSH is sending and receiving RWHO information.");
  3154. #else
  3155.     notify(player, "The MUSH is sending RWHO information.");
  3156. #endif
  3157. #else
  3158.   notify(player, "The MUSH is not connected to an RWHO server.");
  3159. #endif
  3160.  
  3161. #ifdef ALLOW_RPAGE
  3162.   notify(player, "Remote-paging to other MUSHes is enabled.");
  3163. #else
  3164.   notify(player, "Remote-paging to other MUSHes is disabled.");
  3165. #endif
  3166.  
  3167. notify(player, tprintf("The starting location of players is #%d.",
  3168.                PLAYER_START));
  3169.  
  3170. #ifdef DO_GLOBALS
  3171.   notify(player, tprintf("The master room is #%d.", MASTER_ROOM));
  3172. #else
  3173.   notify(player, "There is no master room.");
  3174. #endif
  3175.  
  3176. #ifdef GUEST_RESTRICT
  3177.   notify(player, tprintf("The guest player is #%d.", GUEST_PLAYER));
  3178. #else
  3179.   notify(player, "There is no guest character.");
  3180. #endif
  3181.  
  3182. #ifdef IDLE_TIMEOUT
  3183.   notify(player, 
  3184.      tprintf("The inactivity limit is %d minutes.", INACTIVITY_LIMIT));
  3185. #else
  3186.   notify(player, "There is no inactivity timeout.");
  3187. #endif
  3188.  
  3189. #ifdef LOGIN_LIMIT
  3190.   notify(player,
  3191.      tprintf("The maximum number of logins is %d.", MAX_LOGINS));
  3192. #else
  3193.   notify(player, "There is no maxmium number of logins.");
  3194. #endif
  3195.  
  3196.   notify(player, tprintf("The maximum number of queued commands is %d.",
  3197.              QUEUE_QUOTA));
  3198. }
  3199.  
  3200.